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