1 use darling::{ast, FromDeriveInput, FromVariant};
2
3 #[derive(Debug, FromDeriveInput)]
4 #[darling(attributes(from_variants), supports(enum_any))]
5 pub struct Container {
6 // The second type parameter can be anything that implements FromField, since
7 // FromDeriveInput will produce an error if given a struct.
8 data: ast::Data<Variant, ()>,
9 }
10
11 #[derive(Default, Debug, FromVariant)]
12 #[darling(default, attributes(from_variants), supports(newtype, unit))]
13 pub struct Variant {
14 into: Option<bool>,
15 skip: Option<bool>,
16 }
17
18 #[derive(Debug, FromDeriveInput)]
19 #[darling(attributes(from_struct), supports(struct_named))]
20 pub struct StructContainer {
21 // The second type parameter can be anything that implements FromVariant, since
22 // FromDeriveInput will produce an error if given an enum.
23 data: ast::Data<(), syn::Field>,
24 }
25
26 mod source {
27 use syn::{parse_quote, DeriveInput};
28
newtype_enum() -> DeriveInput29 pub fn newtype_enum() -> DeriveInput {
30 parse_quote! {
31 enum Hello {
32 World(bool),
33 String(String),
34 }
35 }
36 }
37
named_field_enum() -> DeriveInput38 pub fn named_field_enum() -> DeriveInput {
39 parse_quote! {
40 enum Hello {
41 Foo(u16),
42 World {
43 name: String
44 },
45 }
46 }
47 }
48
empty_enum() -> DeriveInput49 pub fn empty_enum() -> DeriveInput {
50 parse_quote! {
51 enum Hello {}
52 }
53 }
54
named_struct() -> DeriveInput55 pub fn named_struct() -> DeriveInput {
56 parse_quote! {
57 struct Hello {
58 world: bool,
59 }
60 }
61 }
62
tuple_struct() -> DeriveInput63 pub fn tuple_struct() -> DeriveInput {
64 parse_quote! { struct Hello(String, bool); }
65 }
66 }
67
68 #[test]
enum_newtype_or_unit()69 fn enum_newtype_or_unit() {
70 // Should pass
71 let container = Container::from_derive_input(&source::newtype_enum()).unwrap();
72 assert!(container.data.is_enum());
73
74 // Should error
75 Container::from_derive_input(&source::named_field_enum()).unwrap_err();
76 Container::from_derive_input(&source::named_struct()).unwrap_err();
77 }
78
79 #[test]
struct_named()80 fn struct_named() {
81 // Should pass
82 let container = StructContainer::from_derive_input(&source::named_struct()).unwrap();
83 assert!(container.data.is_struct());
84
85 // Should fail
86 StructContainer::from_derive_input(&source::tuple_struct()).unwrap_err();
87 StructContainer::from_derive_input(&source::named_field_enum()).unwrap_err();
88 StructContainer::from_derive_input(&source::newtype_enum()).unwrap_err();
89 StructContainer::from_derive_input(&source::empty_enum()).unwrap_err();
90 }
91