diff options
Diffstat (limited to 'syrette_macros/src/libs/intertrait_macros/args.rs')
-rw-r--r-- | syrette_macros/src/libs/intertrait_macros/args.rs | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/syrette_macros/src/libs/intertrait_macros/args.rs b/syrette_macros/src/libs/intertrait_macros/args.rs new file mode 100644 index 0000000..d576ae2 --- /dev/null +++ b/syrette_macros/src/libs/intertrait_macros/args.rs @@ -0,0 +1,99 @@ +/** + * Originally from Intertrait by CodeChain + * + * https://github.com/CodeChain-io/intertrait + * https://crates.io/crates/intertrait/0.2.2 + * + * Licensed under either of + * + * Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) + * MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT) + + * at your option. +*/ +use std::collections::HashSet; + +use syn::bracketed; +use syn::parse::{Parse, ParseStream, Result}; +use syn::punctuated::Punctuated; +use syn::{Error, Ident, Path, Token, Type}; + +#[derive(Hash, PartialEq, Eq)] +pub enum Flag +{ + Sync, +} + +impl Flag +{ + fn from(ident: &Ident) -> Result<Self> + { + match ident.to_string().as_str() { + "sync" => Ok(Flag::Sync), + unknown => { + let msg = format!("Unknown flag: {}", unknown); + Err(Error::new_spanned(ident, msg)) + } + } + } +} + +pub struct Targets +{ + pub flags: HashSet<Flag>, + pub paths: Vec<Path>, +} + +impl Parse for Targets +{ + fn parse(input: ParseStream) -> Result<Self> + { + let mut flags = HashSet::new(); + let mut paths = Vec::new(); + + if input.is_empty() { + return Ok(Targets { flags, paths }); + } + + if input.peek(syn::token::Bracket) { + let content; + bracketed!(content in input); + for ident in Punctuated::<Ident, Token![,]>::parse_terminated(&content)? { + if !flags.insert(Flag::from(&ident)?) { + let msg = format!("Duplicated flag: {}", ident); + return Err(Error::new_spanned(ident, msg)); + } + } + } + + if input.is_empty() { + return Ok(Targets { flags, paths }); + } + + paths = Punctuated::<Path, Token![,]>::parse_terminated(input)? + .into_iter() + .collect(); + + Ok(Targets { flags, paths }) + } +} + +pub struct Casts +{ + pub ty: Type, + pub targets: Targets, +} + +impl Parse for Casts +{ + fn parse(input: ParseStream) -> Result<Self> + { + let ty: Type = input.parse()?; + input.parse::<Token![=>]>()?; + + Ok(Casts { + ty, + targets: input.parse()?, + }) + } +} |