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