From 445e6bbab38f18368abf7229ff4c5004e2846ac8 Mon Sep 17 00:00:00 2001 From: sreenathkrishnan Date: Wed, 13 Apr 2022 06:46:23 -0700 Subject: [PATCH] Improve enum shape validation (#178) * Apply shape validation to enum with no variants. Previously, this would not have produced an error. * If the receiver doesn't support any enum shapes, surface one diagnostic instead of one per variant --- core/src/options/shape.rs | 28 +++++++++++++++++++--------- tests/supports.rs | 7 +++++++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/core/src/options/shape.rs b/core/src/options/shape.rs index 41f6eec..481f906 100644 --- a/core/src/options/shape.rs +++ b/core/src/options/shape.rs @@ -72,18 +72,28 @@ impl ToTokens for Shape { } else { let en = &self.enum_values; let st = &self.struct_values; + + let enum_validation = if en.supports_none() { + let ty = en.prefix.trim_end_matches('_'); + quote!(return ::darling::export::Err(::darling::Error::unsupported_shape(#ty));) + } else { + quote! { + fn validate_variant(data: &::syn::Fields) -> ::darling::Result<()> { + #en + } + + for variant in &data.variants { + validate_variant(&variant.fields)?; + } + + Ok(()) + } + }; + quote! { match *__body { ::syn::Data::Enum(ref data) => { - fn validate_variant(data: &::syn::Fields) -> ::darling::Result<()> { - #en - } - - for variant in &data.variants { - validate_variant(&variant.fields)?; - } - - Ok(()) + #enum_validation } ::syn::Data::Struct(ref struct_data) => { let data = &struct_data.fields; diff --git a/tests/supports.rs b/tests/supports.rs index ae3f2f7..d6c7556 100644 --- a/tests/supports.rs +++ b/tests/supports.rs @@ -46,6 +46,12 @@ mod source { } } + pub fn empty_enum() -> DeriveInput { + parse_quote! { + enum Hello {} + } + } + pub fn named_struct() -> DeriveInput { parse_quote! { struct Hello { @@ -80,4 +86,5 @@ fn struct_named() { StructContainer::from_derive_input(&source::tuple_struct()).unwrap_err(); StructContainer::from_derive_input(&source::named_field_enum()).unwrap_err(); StructContainer::from_derive_input(&source::newtype_enum()).unwrap_err(); + StructContainer::from_derive_input(&source::empty_enum()).unwrap_err(); }