From d1a319c5f280c8b4f30ce9f6d31ce227ef78586f Mon Sep 17 00:00:00 2001 From: Graham Esau Date: Sun, 4 Aug 2019 19:49:41 +0100 Subject: [PATCH] Generate schemas for simple enums --- schemars/src/main.rs | 4 ++-- schemars_derive/src/lib.rs | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/schemars/src/main.rs b/schemars/src/main.rs index e77c95f..533a945 100644 --- a/schemars/src/main.rs +++ b/schemars/src/main.rs @@ -2,7 +2,7 @@ use schemars::MakeSchema; use serde::{Deserialize, Serialize}; use serde_json::Result; -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug, MakeSchema)] #[serde(rename_all = "camelCase")] enum TodoStatus { Backlog, @@ -17,7 +17,7 @@ struct Todo { id: u64, title: String, description: Option, - // status: TodoStatus, + status: TodoStatus, assigned_to: Vec, } diff --git a/schemars_derive/src/lib.rs b/schemars_derive/src/lib.rs index bf83f82..18408c9 100644 --- a/schemars_derive/src/lib.rs +++ b/schemars_derive/src/lib.rs @@ -25,7 +25,8 @@ pub fn derive_make_schema(input: proc_macro::TokenStream) -> proc_macro::TokenSt let fn_contents = match cont.data { Data::Struct(Style::Struct, ref fields) => struct_implementation(fields), - _ => unimplemented!("Only structs work so far!"), + Data::Enum(ref variants) => enum_implementation(variants), + _ => unimplemented!("work in progress!"), }; let impl_block = quote! { @@ -49,6 +50,25 @@ fn compile_error(span: Span, message: String) -> TokenStream { } } +fn is_unit_variant(v: &Variant) -> bool { + match v.style { + Style::Unit => true, + _ => false, + } +} + +fn enum_implementation(variants: &[Variant]) -> TokenStream { + if variants.iter().all(is_unit_variant) { + let names = variants + .into_iter() + .map(|v| v.attrs.name().deserialize_name()); + return quote! { + o.enum_values = Some(vec![#(#names.into()),*]); + }; + } + unimplemented!("work in progress!") +} + fn struct_implementation(fields: &[Field]) -> TokenStream { let recurse = fields.into_iter().map(|f| { let name = f.attrs.name().deserialize_name();