1
0
Fork 0
mirror of https://gitlab.com/msrd0/gotham-restful.git synced 2025-02-22 20:52:27 +00:00

allow deriving enums

This commit is contained in:
Dominic 2019-10-03 00:04:33 +02:00
parent 0b11aaf1f9
commit 50ed2411c9
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
3 changed files with 73 additions and 12 deletions

View file

@ -26,8 +26,17 @@ rest_resource!{Users, route => {
}}
#[derive(Deserialize, OpenapiType, Serialize)]
struct User {
username : String
enum TestEnum
{
Foo,
Bar
}
#[derive(Deserialize, OpenapiType, Serialize)]
struct User
{
username : String,
test : Option<TestEnum>
}
impl ResourceReadAll<Success<Vec<Option<User>>>> for Users
@ -36,7 +45,7 @@ impl ResourceReadAll<Success<Vec<Option<User>>>> for Users
{
vec![Username().fake(), Username().fake()]
.into_iter()
.map(|username| Some(User { username }))
.map(|username| Some(User { username, test: None }))
.collect::<Vec<Option<User>>>()
.into()
}
@ -47,7 +56,7 @@ impl ResourceRead<u64, Success<User>> for Users
fn read(_state : &mut State, id : u64) -> Success<User>
{
let username : String = Username().fake();
User { username: format!("{}{}", username, id) }.into()
User { username: format!("{}{}", username, id), test: None }.into()
}
}

View file

@ -2,7 +2,7 @@
pub mod openapi
{
pub use indexmap::IndexMap;
pub use openapiv3::{ObjectType, ReferenceOr, Schema, SchemaData, SchemaKind, Type};
pub use openapiv3::{ObjectType, ReferenceOr, Schema, SchemaData, SchemaKind, StringType, Type, VariantOrUnknownOrEmpty};
}
#[cfg(not(feature = "openapi"))]

View file

@ -4,10 +4,66 @@ use quote::quote;
use syn::{
Field,
Fields,
Item,
ItemEnum,
ItemStruct,
Variant,
parse_macro_input
};
pub fn expand(tokens : TokenStream) -> TokenStream
{
let input = parse_macro_input!(tokens as Item);
match input {
Item::Enum(item) => expand_enum(item),
Item::Struct(item) => expand_struct(item),
_ => panic!("derive(OpenapiType) not supported for this context")
}.into()
}
fn expand_variant(variant : &Variant) -> TokenStream2
{
if variant.fields != Fields::Unit
{
panic!("Enum Variants with Fields not supported");
}
let ident = &variant.ident;
quote! {
enumeration.push(stringify!(#ident).to_string());
}
}
fn expand_enum(input : ItemEnum) -> TokenStream2
{
let ident = input.ident;
let generics = input.generics;
let variants : Vec<TokenStream2> = input.variants.iter().map(expand_variant).collect();
quote! {
impl #generics ::gotham_restful::OpenapiType for #ident #generics
{
fn to_schema() -> ::gotham_restful::OpenapiSchema
{
use ::gotham_restful::{helper::openapi::*, OpenapiSchema};
let mut enumeration : Vec<String> = Vec::new();
#(#variants)*
OpenapiSchema::new(SchemaKind::Type(Type::String(StringType {
format: VariantOrUnknownOrEmpty::Empty,
pattern: None,
enumeration
})))
}
}
}
}
fn expand_field(field : &Field) -> TokenStream2
{
let ident = match &field.ident {
@ -48,10 +104,8 @@ fn expand_field(field : &Field) -> TokenStream2
}}
}
pub fn expand(tokens : TokenStream) -> TokenStream
pub fn expand_struct(input : ItemStruct) -> TokenStream2
{
let input = parse_macro_input!(tokens as ItemStruct);
let ident = input.ident;
let generics = input.generics;
@ -63,7 +117,7 @@ pub fn expand(tokens : TokenStream) -> TokenStream
Fields::Unit => Vec::new()
};
let output = quote!{
quote!{
impl #generics ::gotham_restful::OpenapiType for #ident #generics
{
fn to_schema() -> ::gotham_restful::OpenapiSchema
@ -92,7 +146,5 @@ pub fn expand(tokens : TokenStream) -> TokenStream
}
}
}
};
output.into()
}
}