1 use darling::FromDeriveInput;
2 use syn::parse_quote;
3 
4 mod foo {
5     pub mod bar {
init() -> String6         pub fn init() -> String {
7             String::from("hello")
8         }
9     }
10 }
11 
12 #[derive(FromDeriveInput)]
13 #[darling(attributes(speak))]
14 pub struct SpeakerOpts {
15     #[darling(default = foo::bar::init)]
16     first_word: String,
17 }
18 
19 #[test]
path_default()20 fn path_default() {
21     let speaker: SpeakerOpts = FromDeriveInput::from_derive_input(&parse_quote! {
22         struct Foo;
23     })
24     .expect("Unit struct with no attrs should parse");
25 
26     assert_eq!(speaker.first_word, "hello");
27 }
28 
29 /// Tests in this module capture the somewhat-confusing behavior observed when defaults
30 /// are set at both the field and container level.
31 ///
32 /// The general rule is that more-specific declarations preempt less-specific ones; this is
33 /// unsurprising and allows for granular control over what happens when parsing an AST.
34 mod stacked_defaults {
35     use darling::{FromDeriveInput, FromMeta};
36     use syn::parse_quote;
37 
jane() -> String38     fn jane() -> String {
39         "Jane".into()
40     }
41 
42     #[derive(FromMeta)]
43     #[darling(default)]
44     struct PersonName {
45         #[darling(default = "jane")]
46         first: String,
47         #[darling(default)]
48         middle: String,
49         last: String,
50     }
51 
52     impl Default for PersonName {
default() -> Self53         fn default() -> Self {
54             Self {
55                 first: "John".into(),
56                 middle: "T".into(),
57                 last: "Doe".into(),
58             }
59         }
60     }
61 
62     #[derive(FromDeriveInput)]
63     #[darling(attributes(person))]
64     struct Person {
65         #[darling(default)]
66         name: PersonName,
67         age: u8,
68     }
69 
70     #[test]
name_first_only()71     fn name_first_only() {
72         let person = Person::from_derive_input(&parse_quote! {
73             #[person(name(first = "Bill"), age = 5)]
74             struct Foo;
75         })
76         .unwrap();
77 
78         assert_eq!(person.name.first, "Bill");
79         assert_eq!(
80             person.name.middle, "",
81             "Explicit field-level default should preempt container-level default"
82         );
83         assert_eq!(
84             person.name.last, "Doe",
85             "Absence of a field-level default falls back to container-level default"
86         );
87     }
88 
89     /// This is the most surprising case. The presence of `name()` means we invoke
90     /// `PersonName::from_list(&[])`. When that finishes parsing each of the zero nested
91     /// items it has received, it will then start filling in missing fields, using the
92     /// explicit field-level defaults for `first` and `middle`, while for `last` it will
93     /// use the `last` field from the container-level default.
94     #[test]
name_empty_list()95     fn name_empty_list() {
96         let person = Person::from_derive_input(&parse_quote! {
97             #[person(name(), age = 5)]
98             struct Foo;
99         })
100         .unwrap();
101 
102         assert_eq!(person.name.first, "Jane");
103         assert_eq!(person.name.middle, "");
104         assert_eq!(person.name.last, "Doe");
105     }
106 
107     #[test]
no_name()108     fn no_name() {
109         let person = Person::from_derive_input(&parse_quote! {
110             #[person(age = 5)]
111             struct Foo;
112         })
113         .unwrap();
114 
115         assert_eq!(person.age, 5);
116         assert_eq!(
117             person.name.first, "John",
118             "If `name` is not specified, `Person`'s field-level default should be used"
119         );
120         assert_eq!(person.name.middle, "T");
121         assert_eq!(person.name.last, "Doe");
122     }
123 }
124 
125 mod implicit_default {
126     use darling::{util::Flag, FromDeriveInput};
127     use syn::parse_quote;
128 
129     // No use of `darling(default)` here at all!
130     // This struct will fill in missing fields using FromMeta::from_none.
131     #[derive(FromDeriveInput)]
132     #[darling(attributes(person))]
133     struct Person {
134         first_name: String,
135         last_name: Option<String>,
136         lefty: Flag,
137     }
138 
139     #[test]
missing_fields_fill()140     fn missing_fields_fill() {
141         let person = Person::from_derive_input(&parse_quote! {
142             #[person(first_name = "James")]
143             struct Foo;
144         })
145         .unwrap();
146 
147         assert_eq!(person.first_name, "James");
148         assert_eq!(person.last_name, None);
149         assert!(!person.lefty.is_present());
150     }
151 }
152 
153 /// Test that a field-level implicit default using FromMeta::from_none is superseded
154 /// by the parent declaring `#[darling(default)]`.
155 mod overridden_implicit_default {
156     use darling::{util::Flag, FromDeriveInput};
157     use syn::parse_quote;
158 
159     #[derive(FromDeriveInput)]
160     #[darling(default, attributes(person))]
161     struct Person {
162         first_name: String,
163         last_name: Option<String>,
164         lefty: Flag,
165     }
166 
167     impl Default for Person {
default() -> Self168         fn default() -> Self {
169             Self {
170                 first_name: "Jane".into(),
171                 last_name: Some("Doe".into()),
172                 lefty: Flag::default(),
173             }
174         }
175     }
176 
177     #[test]
fill_missing()178     fn fill_missing() {
179         let person = Person::from_derive_input(&parse_quote!(
180             #[person(last_name = "Archer")]
181             struct Foo;
182         ))
183         .unwrap();
184 
185         assert_eq!(person.first_name, "Jane");
186         assert_eq!(person.last_name, Some("Archer".into()));
187         assert!(!person.lefty.is_present());
188     }
189 }
190