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