bon_macros/normalization/cfg/
parse.rs
1use crate::util::prelude::*;
2use syn::parse::{Parse, ParseStream};
3use syn::punctuated::Punctuated;
4
5mod kw {
6 syn::custom_keyword!(__cfgs);
7}
8
9pub(crate) fn parse_predicate_results(tokens: TokenStream) -> Result<Option<PredicateResults>> {
10 let results: WrapOption<PredicateResults> = syn::parse2(tokens)?;
11 Ok(results.0)
12}
13
14#[derive(Debug)]
16struct WrapOption<T>(Option<T>);
17
18#[derive(Debug)]
22pub(crate) struct PredicateResults {
23 pub(crate) results: Vec<bool>,
24 pub(crate) recursion_counter: usize,
25 pub(crate) rest: TokenStream,
26}
27
28impl Parse for WrapOption<PredicateResults> {
29 fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
30 if !input.peek(kw::__cfgs) {
31 input.parse::<TokenStream>()?;
33
34 return Ok(Self(None));
35 }
36
37 input.parse::<kw::__cfgs>()?;
38
39 let results;
40 syn::parenthesized!(results in input);
41
42 let recursion_counter: syn::LitInt = results.parse()?;
43 let recursion_counter = recursion_counter.base10_parse::<usize>()?;
44
45 results.parse::<syn::Token![,]>()?;
46
47 let results: Vec<bool> =
48 Punctuated::<syn::LitBool, syn::Token![,]>::parse_terminated(&results)?
49 .into_iter()
50 .map(|bool| bool.value)
51 .collect();
52
53 let results = PredicateResults {
54 results,
55 recursion_counter,
56 rest: input.parse()?,
57 };
58
59 Ok(Self(Some(results)))
60 }
61}
62
63pub(crate) enum CfgSyntax {
64 Cfg(TokenStream),
65 CfgAttr(CfgAttr),
66}
67
68impl CfgSyntax {
69 pub(crate) fn from_meta(meta: &syn::Meta) -> Result<Option<Self>> {
70 let meta = match meta {
71 syn::Meta::List(meta) => meta,
72 _ => return Ok(None),
73 };
74
75 if meta.path.is_ident("cfg") {
76 return Ok(Some(Self::Cfg(meta.tokens.clone())));
77 }
78
79 if meta.path.is_ident("cfg_attr") {
80 let cfg_attr = syn::parse2(meta.tokens.clone())?;
81 return Ok(Some(Self::CfgAttr(cfg_attr)));
82 }
83
84 Ok(None)
85 }
86}
87
88pub(crate) struct CfgAttr {
89 pub(crate) predicate: syn::Meta,
90 pub(crate) then_branch: Punctuated<syn::Meta, syn::Token![,]>,
91}
92
93impl Parse for CfgAttr {
94 fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
95 let predicate = input.parse()?;
96 input.parse::<syn::Token![,]>()?;
97
98 let then_branch = Punctuated::<syn::Meta, syn::Token![,]>::parse_terminated(input)?;
99
100 Ok(Self {
101 predicate,
102 then_branch,
103 })
104 }
105}