api: Parameter::type_info must be an fn

while filling the Parameter fields as &'static we cannot
really make use of the get_type_info() yet because it would
need to be a `const fn` (possible via #!feature(const_fn)),
so for now we store the method pointer until `const_fn` is
stable

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2019-06-12 16:43:24 +02:00
parent 1a279f54a9
commit 23d8e1d4e0
3 changed files with 24 additions and 7 deletions

View File

@ -4,7 +4,7 @@ use proc_macro2::{Delimiter, Ident, Span, TokenStream, TokenTree};
use failure::{bail, format_err, Error};
use quote::{quote, ToTokens};
use syn::Token;
use syn::{Expr, Token};
use super::api_def::ParameterDefinition;
use super::parsing::*;
@ -85,7 +85,7 @@ fn handle_function(
.map(|v| v.expect_object())
.transpose()?
.unwrap_or_else(HashMap::new);
let mut parameter_tokens = TokenStream::new();
let mut parameter_entries = TokenStream::new();
let vis = std::mem::replace(&mut item.vis, syn::Visibility::Inherited);
let span = item.ident.span();
@ -114,6 +114,7 @@ fn handle_function(
other => bail!("unhandled type of method parameter ({:?})", other),
};
let arg_type = &arg.ty;
let name = match &arg.pat {
syn::Pat::Ident(name) => &name.ident,
other => bail!("invalid kind of parameter pattern: {:?}", other),
@ -132,9 +133,25 @@ fn handle_function(
)?;
});
let _info = parameters
let info = parameters
.remove(&name_str)
.ok_or_else(|| format_err!("missing parameter '{}' in api defintion", name_str))?;
match info {
Expression::Expr(Expr::Lit(lit)) => {
parameter_entries.extend(quote! {
::proxmox::api::Parameter {
name: #name_str,
description: #lit,
type_info: <#arg_type as ::proxmox::api::ApiType>::type_info,
},
});
}
Expression::Expr(_) => bail!("description must be a string literal!"),
Expression::Object(_) => {
bail!("TODO: parameters with more than just a description...");
}
}
}
if !parameters.is_empty() {
@ -297,7 +314,7 @@ fn handle_function(
fn parameters(&self) -> &'static [::proxmox::api::Parameter] {
// FIXME!
&[]
&[ #parameter_entries ]
}
fn return_type(&self) -> &'static ::proxmox::api::TypeInfo {

View File

@ -28,7 +28,7 @@ pub type CompleteFn = fn(&str) -> Vec<String>;
pub struct Parameter {
pub name: &'static str,
pub description: &'static str,
pub type_info: &'static TypeInfo,
pub type_info: fn() -> &'static TypeInfo,
}
/// Bare type info. Types themselves should also have a description, even if a method's parameter

View File

@ -116,7 +116,7 @@ mod methods {
vec![Parameter {
name: "person",
description: "the person to get",
type_info: get_type_info::<String>(),
type_info: String::type_info,
}]
};
pub static ref GET_PEOPLE: ApiMethod<Bytes> = {
@ -133,7 +133,7 @@ mod methods {
vec![Parameter {
name: "subpath",
description: "the matched relative subdir path",
type_info: get_type_info::<String>(),
type_info: String::type_info,
}]
};
pub static ref GET_SUBPATH: ApiMethod<Bytes> = {