diff options
Diffstat (limited to 'macros/src/declare_interface_args.rs')
-rw-r--r-- | macros/src/declare_interface_args.rs | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/macros/src/declare_interface_args.rs b/macros/src/declare_interface_args.rs index b54f458..bd2f24e 100644 --- a/macros/src/declare_interface_args.rs +++ b/macros/src/declare_interface_args.rs @@ -1,10 +1,17 @@ use syn::parse::{Parse, ParseStream, Result}; +use syn::punctuated::Punctuated; use syn::{Path, Token, Type}; +use crate::macro_flag::MacroFlag; +use crate::util::iterator_ext::IteratorExt; + +pub const DECLARE_INTERFACE_FLAGS: &[&str] = &["async"]; + pub struct DeclareInterfaceArgs { pub implementation: Type, pub interface: Path, + pub flags: Punctuated<MacroFlag, Token![,]>, } impl Parse for DeclareInterfaceArgs @@ -15,9 +22,43 @@ impl Parse for DeclareInterfaceArgs input.parse::<Token![->]>()?; + let interface: Path = input.parse()?; + + let flags = if input.peek(Token![,]) { + input.parse::<Token![,]>()?; + + let flags = Punctuated::<MacroFlag, Token![,]>::parse_terminated(input)?; + + for flag in &flags { + let flag_str = flag.flag.to_string(); + + if !DECLARE_INTERFACE_FLAGS.contains(&flag_str.as_str()) { + return Err(input.error(format!( + "Unknown flag '{}'. Expected one of [ {} ]", + flag_str, + DECLARE_INTERFACE_FLAGS.join(",") + ))); + } + } + + let flag_names = flags + .iter() + .map(|flag| flag.flag.to_string()) + .collect::<Vec<_>>(); + + if let Some(dupe_flag_name) = flag_names.iter().find_duplicate() { + return Err(input.error(format!("Duplicate flag '{}'", dupe_flag_name))); + } + + flags + } else { + Punctuated::new() + }; + Ok(Self { implementation, - interface: input.parse()?, + interface, + flags, }) } } |