mirror of
https://git.proxmox.com/git/proxmox
synced 2025-08-08 16:29:11 +00:00
api-macro: make return schema optional
and support returning () from methods Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
354cfabd37
commit
a997502ab1
@ -21,10 +21,12 @@ pub fn handle_method(mut attribs: JSONObject, mut func: syn::ItemFn) -> Result<T
|
|||||||
.into_object("input schema definition")?
|
.into_object("input schema definition")?
|
||||||
.try_into()?;
|
.try_into()?;
|
||||||
|
|
||||||
let mut returns_schema: Schema = attribs
|
let mut returns_schema: Option<Schema> = attribs
|
||||||
.remove_required_element("returns")?
|
.remove("returns")
|
||||||
.into_object("return schema definition")?
|
.map(|ret| ret.into_object("return schema definition"))
|
||||||
.try_into()?;
|
.transpose()?
|
||||||
|
.map(|ret| ret.try_into())
|
||||||
|
.transpose()?;
|
||||||
|
|
||||||
let protected: bool = attribs
|
let protected: bool = attribs
|
||||||
.remove("protected")
|
.remove("protected")
|
||||||
@ -50,7 +52,14 @@ pub fn handle_method(mut attribs: JSONObject, mut func: syn::ItemFn) -> Result<T
|
|||||||
|
|
||||||
let returns_schema = {
|
let returns_schema = {
|
||||||
let mut ts = TokenStream::new();
|
let mut ts = TokenStream::new();
|
||||||
returns_schema.to_schema(&mut ts)?;
|
match returns_schema {
|
||||||
|
Some(schema) => {
|
||||||
|
let mut inner = TokenStream::new();
|
||||||
|
schema.to_schema(&mut inner)?;
|
||||||
|
ts.extend(quote! { .returns(#inner) });
|
||||||
|
}
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
ts
|
ts
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,7 +76,7 @@ pub fn handle_method(mut attribs: JSONObject, mut func: syn::ItemFn) -> Result<T
|
|||||||
&::proxmox::api::ApiHandler::Sync(&#api_func_name),
|
&::proxmox::api::ApiHandler::Sync(&#api_func_name),
|
||||||
&#input_schema,
|
&#input_schema,
|
||||||
)
|
)
|
||||||
.returns(#returns_schema)
|
#returns_schema
|
||||||
.protected(#protected);
|
.protected(#protected);
|
||||||
#wrapper_ts
|
#wrapper_ts
|
||||||
#func
|
#func
|
||||||
@ -77,7 +86,7 @@ pub fn handle_method(mut attribs: JSONObject, mut func: syn::ItemFn) -> Result<T
|
|||||||
|
|
||||||
fn api_function_attributes(
|
fn api_function_attributes(
|
||||||
input_schema: &mut Schema,
|
input_schema: &mut Schema,
|
||||||
returns_schema: &mut Schema,
|
returns_schema: &mut Option<Schema>,
|
||||||
attrs: &mut Vec<syn::Attribute>,
|
attrs: &mut Vec<syn::Attribute>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let mut doc_comment = String::new();
|
let mut doc_comment = String::new();
|
||||||
@ -107,7 +116,7 @@ fn api_function_attributes(
|
|||||||
|
|
||||||
fn derive_descriptions(
|
fn derive_descriptions(
|
||||||
input_schema: &mut Schema,
|
input_schema: &mut Schema,
|
||||||
returns_schema: &mut Schema,
|
returns_schema: &mut Option<Schema>,
|
||||||
doc_comment: &str,
|
doc_comment: &str,
|
||||||
doc_span: Span,
|
doc_span: Span,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
@ -126,16 +135,18 @@ fn derive_descriptions(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(second) = parts.next() {
|
if let Some(second) = parts.next() {
|
||||||
if returns_schema.description.is_none() {
|
if let Some(ref mut returns_schema) = returns_schema {
|
||||||
returns_schema.description = Some(syn::LitStr::new(second.trim(), doc_span));
|
if returns_schema.description.is_none() {
|
||||||
|
returns_schema.description = Some(syn::LitStr::new(second.trim(), doc_span));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if parts.next().is_some() {
|
if parts.next().is_some() {
|
||||||
bail!(
|
bail!(
|
||||||
doc_span,
|
doc_span,
|
||||||
"multiple 'Returns:' sections found in doc comment!"
|
"multiple 'Returns:' sections found in doc comment!"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -150,7 +161,7 @@ enum ParameterType<'a> {
|
|||||||
|
|
||||||
fn handle_function_signature(
|
fn handle_function_signature(
|
||||||
input_schema: &mut Schema,
|
input_schema: &mut Schema,
|
||||||
returns_schema: &mut Schema,
|
returns_schema: &mut Option<Schema>,
|
||||||
func: &mut syn::ItemFn,
|
func: &mut syn::ItemFn,
|
||||||
wrapper_ts: &mut TokenStream,
|
wrapper_ts: &mut TokenStream,
|
||||||
) -> Result<Ident, Error> {
|
) -> Result<Ident, Error> {
|
||||||
@ -304,7 +315,7 @@ fn is_value_type(ty: &syn::Type) -> bool {
|
|||||||
|
|
||||||
fn create_wrapper_function(
|
fn create_wrapper_function(
|
||||||
_input_schema: &Schema,
|
_input_schema: &Schema,
|
||||||
_returns_schema: &Schema,
|
returns_schema: &Option<Schema>,
|
||||||
param_list: Vec<(SimpleIdent, ParameterType)>,
|
param_list: Vec<(SimpleIdent, ParameterType)>,
|
||||||
func: &syn::ItemFn,
|
func: &syn::ItemFn,
|
||||||
wrapper_ts: &mut TokenStream,
|
wrapper_ts: &mut TokenStream,
|
||||||
@ -316,6 +327,7 @@ fn create_wrapper_function(
|
|||||||
|
|
||||||
let mut body = TokenStream::new();
|
let mut body = TokenStream::new();
|
||||||
let mut args = TokenStream::new();
|
let mut args = TokenStream::new();
|
||||||
|
let mut return_stmt = TokenStream::new();
|
||||||
|
|
||||||
for (name, param) in param_list {
|
for (name, param) in param_list {
|
||||||
let span = name.span();
|
let span = name.span();
|
||||||
@ -354,6 +366,17 @@ fn create_wrapper_function(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if returns_schema.is_some() {
|
||||||
|
return_stmt.extend(quote! {
|
||||||
|
Ok(::serde_json::to_value(output)?)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return_stmt.extend(quote! {
|
||||||
|
let _ = output;
|
||||||
|
Ok(::serde_json::Value::Null)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// build the wrapping function:
|
// build the wrapping function:
|
||||||
let func_name = &func.sig.ident;
|
let func_name = &func.sig.ident;
|
||||||
wrapper_ts.extend(quote! {
|
wrapper_ts.extend(quote! {
|
||||||
@ -364,7 +387,8 @@ fn create_wrapper_function(
|
|||||||
) -> Result<::serde_json::Value, ::failure::Error> {
|
) -> Result<::serde_json::Value, ::failure::Error> {
|
||||||
if let ::serde_json::Value::Object(ref mut input_map) = &mut input_params {
|
if let ::serde_json::Value::Object(ref mut input_map) = &mut input_params {
|
||||||
#body
|
#body
|
||||||
Ok(::serde_json::to_value(#func_name(#args)?)?)
|
let output = #func_name(#args)?;
|
||||||
|
#return_stmt
|
||||||
} else {
|
} else {
|
||||||
::failure::bail!("api function wrapper called with a non-object json value");
|
::failure::bail!("api function wrapper called with a non-object json value");
|
||||||
}
|
}
|
||||||
|
@ -84,3 +84,19 @@ pub fn create_ticket_direct(username: String, password: String) -> Result<&'stat
|
|||||||
// successfully produce a `serde_json::Value`!
|
// successfully produce a `serde_json::Value`!
|
||||||
Ok("an:invalid:ticket")
|
Ok("an:invalid:ticket")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api(
|
||||||
|
input: {
|
||||||
|
properties: {
|
||||||
|
verbose: {
|
||||||
|
type: Boolean,
|
||||||
|
description: "Verbose output.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)]
|
||||||
|
/// Test something
|
||||||
|
pub fn some_call(verbose: bool) -> Result<(), Error> {
|
||||||
|
let _ = verbose;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user