1 use darling::{ast, util::Ignored, FromDeriveInput, FromField, FromMeta};
2 use proc_macro2::{Ident, Span};
3 use syn::parse_quote;
4 
5 #[derive(FromMeta)]
6 struct Vis {
7     #[darling(default)]
8     public: bool,
9     #[darling(default)]
10     private: bool,
11 }
12 
13 #[derive(FromField)]
14 #[darling(attributes(v))]
15 struct Field {
16     ident: Option<Ident>,
17     example: Option<String>,
18     #[darling(flatten)]
19     visibility: Vis,
20 }
21 
22 #[derive(FromDeriveInput)]
23 #[darling(attributes(v))]
24 struct Input {
25     data: ast::Data<Ignored, Field>,
26 }
27 
28 #[test]
field_flattens()29 fn field_flattens() {
30     let di = Input::from_derive_input(&parse_quote! {
31         struct Demo {
32             #[v(public, example = "world")]
33             hello: String
34         }
35     })
36     .unwrap();
37 
38     let fields = di.data.take_struct().unwrap();
39     let first_field = fields.into_iter().next().unwrap();
40     assert_eq!(
41         first_field.ident,
42         Some(Ident::new("hello", Span::call_site()))
43     );
44     assert!(first_field.visibility.public);
45     assert!(!first_field.visibility.private);
46     assert_eq!(first_field.example.unwrap(), "world");
47 }
48 
49 #[test]
field_flattens_with_no_field_level_attributes()50 fn field_flattens_with_no_field_level_attributes() {
51     let di = Input::from_derive_input(&parse_quote! {
52         struct Demo {
53             hello: String
54         }
55     })
56     .unwrap();
57 
58     let fields = di.data.take_struct().unwrap();
59     let first_field = fields.into_iter().next().unwrap();
60     assert_eq!(
61         first_field.ident,
62         Some(Ident::new("hello", Span::call_site()))
63     );
64     assert!(!first_field.visibility.public);
65     assert!(!first_field.visibility.private);
66     assert_eq!(first_field.example, None);
67 }
68 
69 #[test]
field_flattens_across_attributes()70 fn field_flattens_across_attributes() {
71     let di = Input::from_derive_input(&parse_quote! {
72         struct Demo {
73             #[v(public)]
74             #[v(private)]
75             hello: String
76         }
77     })
78     .unwrap();
79 
80     let fields = di.data.take_struct().unwrap();
81     let first_field = fields.into_iter().next().unwrap();
82     assert!(first_field.visibility.public);
83     assert!(first_field.visibility.private);
84 }
85