1use syn::{
2 parse::{Parse, ParseStream},
3 punctuated::Punctuated,
4 token, Attribute, Expr, Ident, Token, Type, Visibility,
5};
6
7#[allow(dead_code)]
8pub(super) struct Input {
9 struct_attrs: Vec<Attribute>,
10 vis: Visibility,
11 struct_token: Token![struct],
12 ident: Ident,
13 colon_token: Token![:],
14 ty: Type,
15 brace_token: token::Brace,
16 flags: Punctuated<Flag, Token![;]>,
17}
18
19impl Parse for Input {
20 fn parse(input: ParseStream) -> syn::Result<Self> {
21 let flags: ParseBuffer<'_>;
22 Ok(Self {
23 struct_attrs: Attribute::parse_outer(input)?,
24 vis: input.parse()?,
25 struct_token: input.parse()?,
26 ident: input.parse()?,
27 colon_token: input.parse()?,
28 ty: input.parse()?,
29 brace_token: syn::braced!(flags in input),
30 flags: Punctuated::parse_terminated(&flags)?,
31 })
32 }
33}
34
35impl Input {
36 pub(super) fn flags(&self) -> impl Iterator<Item = &Flag> {
37 self.flags.iter()
38 }
39
40 pub(super) fn ident(&self) -> &Ident {
41 &self.ident
42 }
43
44 pub(super) fn ty(&self) -> &Type {
45 &self.ty
46 }
47}
48
49#[allow(dead_code)]
50pub(super) struct Flag {
51 cfg_attrs: Vec<Attribute>,
52 const_attrs: Vec<Attribute>,
53 const_token: Token![const],
54 ident: Ident,
55 eq_token: Token![=],
56 value: Expr,
57}
58
59impl Parse for Flag {
60 fn parse(input: ParseStream) -> syn::Result<Self> {
61 let const_attrs: Vec = Attribute::parse_outer(input)?;
62 Ok(Self {
63 cfg_attrs: extract_cfgs(&const_attrs),
64 const_attrs,
65 const_token: input.parse()?,
66 ident: input.parse()?,
67 eq_token: input.parse()?,
68 value: input.parse()?,
69 })
70 }
71}
72
73impl Flag {
74 pub(super) fn cfg_attrs(&self) -> &[Attribute] {
75 &self.cfg_attrs
76 }
77
78 pub(super) fn ident(&self) -> &Ident {
79 &self.ident
80 }
81}
82
83fn extract_cfgs(attrs: &[Attribute]) -> Vec<Attribute> {
84 let mut cfgs: Vec = vec![];
85
86 for attr: &Attribute in attrs {
87 if attr.path().is_ident("cfg") {
88 cfgs.push(attr.clone());
89 }
90 }
91
92 cfgs
93}
94