use crate::co::CoMacroFeature;
use proc_macro::TokenStream;
use std::collections::BTreeSet;
use syn::{
parse::{Parse, ParseStream},
punctuated::Punctuated,
Meta, Token,
};
mod co;
mod tagged_fields;
struct CoArgs {
features: BTreeSet<CoMacroFeature>,
}
impl Parse for CoArgs {
fn parse(input: ParseStream) -> syn::Result<Self> {
let args = Punctuated::<Meta, Token![,]>::parse_terminated(input)?;
let mut features = BTreeSet::new();
for arg in &args {
let flag = match arg {
Meta::Path(path) => path.get_ident().map(|id| id.to_string()),
other => {
return Err(syn::Error::new_spanned(other, "Expected flag-style identifiers"));
},
};
if let Some(flag) = flag {
match CoMacroFeature::try_from(flag.as_str()) {
Ok(flag) => {
features.insert(flag);
},
Err(err) => {
return Err(err);
},
}
}
}
Ok(Self { features })
}
}
#[proc_macro_attribute]
pub fn co(metadata: TokenStream, input: TokenStream) -> TokenStream {
let args = syn::parse_macro_input!(metadata as CoArgs);
co::macro_co(input, args.features)
}
#[proc_macro_derive(TaggedFields, attributes(tagged))]
pub fn derive_tagged_fields(item: TokenStream) -> TokenStream {
tagged_fields::derive_tagged_fields(item)
}