1 use darling::{FromDeriveInput, FromMeta};
2 use syn::parse_quote;
3 
4 #[derive(Debug, Default, PartialEq, Eq, FromMeta)]
5 #[darling(default)]
6 pub struct Amet {
7     hello: bool,
8     world: String,
9 }
10 
11 #[derive(Debug, PartialEq, Eq, FromMeta)]
12 #[darling(rename_all = "snake_case")]
13 pub enum Lorem {
14     Ipsum(bool),
15     Dolor(String),
16     OptDolor(Option<String>),
17     Sit(Amet),
18 }
19 
20 #[derive(Debug, PartialEq, Eq, FromDeriveInput)]
21 #[darling(attributes(hello))]
22 pub struct Holder {
23     lorem: Lorem,
24 }
25 
26 impl PartialEq<Lorem> for Holder {
eq(&self, other: &Lorem) -> bool27     fn eq(&self, other: &Lorem) -> bool {
28         self.lorem == *other
29     }
30 }
31 
32 #[test]
bool_word()33 fn bool_word() {
34     let di = parse_quote! {
35         #[hello(lorem(ipsum))]
36         pub struct Bar;
37     };
38 
39     let pr = Holder::from_derive_input(&di).unwrap();
40     assert_eq!(pr, Lorem::Ipsum(true));
41 }
42 
43 #[test]
bool_literal()44 fn bool_literal() {
45     let di = parse_quote! {
46         #[hello(lorem(ipsum = false))]
47         pub struct Bar;
48     };
49 
50     let pr = Holder::from_derive_input(&di).unwrap();
51     assert_eq!(pr, Lorem::Ipsum(false));
52 }
53 
54 #[test]
string_literal()55 fn string_literal() {
56     let di = parse_quote! {
57         #[hello(lorem(dolor = "Hello"))]
58         pub struct Bar;
59     };
60 
61     let pr = Holder::from_derive_input(&di).unwrap();
62     assert_eq!(pr, Lorem::Dolor("Hello".to_string()));
63 }
64 
65 #[test]
option_literal()66 fn option_literal() {
67     let holder = Holder::from_derive_input(&parse_quote! {
68         #[hello(lorem(opt_dolor = "Hello"))]
69         struct Bar;
70     })
71     .unwrap();
72 
73     assert_eq!(holder.lorem, Lorem::OptDolor(Some("Hello".into())));
74 }
75 
76 /// Make sure newtype variants whose field's type's `from_none` return
77 /// a `Some` can be used in key-value form.
78 #[test]
option_word_only()79 fn option_word_only() {
80     let holder = Holder::from_derive_input(&parse_quote! {
81         #[hello(lorem = "opt_dolor")]
82         struct Bar;
83     })
84     .unwrap();
85 
86     assert_eq!(holder.lorem, Lorem::OptDolor(None));
87 }
88 
89 /// Make sure that newtype variants which don't produce a from_none value
90 /// do not allow the word form.
91 #[test]
92 #[should_panic]
word_only_fails_for_non_option()93 fn word_only_fails_for_non_option() {
94     Holder::from_derive_input(&parse_quote! {
95         #[hello(lorem = "dolor")]
96         struct Bar;
97     })
98     .unwrap();
99 }
100 
101 #[test]
struct_nested()102 fn struct_nested() {
103     let di = parse_quote! {
104         #[hello(lorem(sit(world = "Hello", hello = false)))]
105         pub struct Bar;
106     };
107 
108     let pr = Holder::from_derive_input(&di).unwrap();
109     assert_eq!(
110         pr,
111         Lorem::Sit(Amet {
112             hello: false,
113             world: "Hello".to_string(),
114         })
115     );
116 }
117 
118 #[test]
119 #[should_panic]
format_mismatch()120 fn format_mismatch() {
121     let di = parse_quote! {
122         #[hello(lorem(dolor(world = "Hello", hello = false)))]
123         pub struct Bar;
124     };
125 
126     Holder::from_derive_input(&di).unwrap();
127 }
128