1 #[macro_use]
2 extern crate darling;
3 
4 extern crate syn;
5 
6 use darling::FromDeriveInput;
7 
8 #[derive(FromMeta, PartialEq, Eq, Debug)]
9 enum Volume {
10     Whisper,
11     Talk,
12     Shout,
13 }
14 
15 /// A more complex example showing the ability to skip at a field or struct
16 /// level while still tracking which type parameters need to be bounded.
17 /// This can be seen by expanding this example using `cargo expand`.
18 #[derive(FromMeta)]
19 #[allow(dead_code)]
20 enum Emphasis<T> {
21     Constant(Volume),
22     Variable(darling::util::PathList),
23     #[darling(skip)]
24     PerPhoneme(Option<T>),
25     Strided {
26         #[darling(skip)]
27         step: Vec<T>,
28         #[darling(multiple)]
29         volume: Vec<Volume>,
30     },
31 }
32 
33 #[derive(FromDeriveInput)]
34 #[darling(attributes(speak))]
35 struct SpeakingOptions<T, U> {
36     max_volume: U,
37     #[darling(skip, default)]
38     additional_data: Vec<T>,
39 }
40 
41 #[derive(Default)]
42 struct Phoneme {
43     #[allow(dead_code)]
44     first: String,
45 }
46 
47 // This is probably the holy grail for `darling`'s own internal use-case:
48 // Auto-apply `Default` bound to skipped *field* types in `where` clause.
49 impl<T, U> Default for SpeakingOptions<T, U>
50 where
51     Vec<T>: Default,
52     U: Default,
53 {
default() -> Self54     fn default() -> Self {
55         Self {
56             max_volume: Default::default(),
57             additional_data: Default::default(),
58         }
59     }
60 }
61 
main()62 fn main() {
63     let derive_input = syn::parse_str(
64         r#"
65         #[derive(Speak)]
66         #[speak(max_volume = "shout")]
67         enum HtmlElement {
68             Div(String)
69         }
70     "#,
71     )
72     .unwrap();
73 
74     let parsed: SpeakingOptions<Phoneme, Volume> =
75         FromDeriveInput::from_derive_input(&derive_input).unwrap();
76     assert_eq!(parsed.max_volume, Volume::Shout);
77     assert_eq!(parsed.additional_data.len(), 0);
78 }
79