My #[proc_macro_attribute] optionally accepts config flags as a meta list. So I used syn's syn::meta::parser to read the attributes.
However, it fails when the meta list is empty, with no way of controlling this behavior.
Say I have a Config struct as follow:
#[derive(Default)]
pub(crate) struct Config {
zoobi_whoop: Option<Ident>,
badhi_wabbi: Option<Ident>,
bopple_beep: Option<syn::Visibility>,
}
I have a parse method on Config as follow, similar to the one in the doc example:
match () {
() if meta.path.is_ident("zoobi_whoop") => {
let value = meta.value()?;
self.zoobi_whoop = Some(value.parse()?);
}
// ... parse badhi_wabbi and bopple_beep
() => {
return Err(meta.error("Unrecognized do_woobah meta attribute"));
}
}
Ok(())
I will use syn::meta::parser as follow:
#[proc_macro_attribute]
pub fn do_woobah(attrs: TokenStream1, input: TokenStream1) -> TokenStream1 {
let mut config = Config::default();
let config_parser = syn::meta::parser(|meta| config.parse(meta));
parse_macro_input!(attrs with config_parser);
// Use `config` here
}
I can call do_woobah as follow:
#[do_woobah(zoobi_whoop = beep_bop)]
fn wobble_function() {}
However, usually, do_woobah doesn't have a meta list, the default config values are enough most of the time.
#[do_woobah]
fn wobble_function() {}
This fails to compile when using syn::meta::parser. To me, it doesn't make sense that this should fail. I don't see the interest in failing on an empty meta list.
Say you have mandatory config options. Regardless of whether the options are mandatory or not, you still need to check afterward that all mandatory config options are set, and ideally tell the user what to options are missing, so this behavior is unwishable in this case as well.
Workaround
Thankfully, TokenStream exposes a is_empty() method, and I can use it to avoid running syn::meta::parse when attrs is empty:
pub fn do_woobah(attrs: TokenStream1, input: TokenStream1) -> TokenStream1 {
let mut config = Config::default();
if !attrs.is_empty() {
let config_parser = syn::meta::parser(|meta| config.parse(meta));
parse_macro_input!(attrs with config_parser);
}
// Use `config` here
}
My
#[proc_macro_attribute]optionally accepts config flags as a meta list. So I usedsyn'ssyn::meta::parserto read the attributes.However, it fails when the meta list is empty, with no way of controlling this behavior.
Say I have a
Configstruct as follow:I have a parse method on
Configas follow, similar to the one in the doc example:I will use
syn::meta::parseras follow:I can call
do_woobahas follow:However, usually,
do_woobahdoesn't have a meta list, the default config values are enough most of the time.This fails to compile when using
syn::meta::parser. To me, it doesn't make sense that this should fail. I don't see the interest in failing on an empty meta list.Say you have mandatory config options. Regardless of whether the options are mandatory or not, you still need to check afterward that all mandatory config options are set, and ideally tell the user what to options are missing, so this behavior is unwishable in this case as well.
Workaround
Thankfully,
TokenStreamexposes ais_empty()method, and I can use it to avoid runningsyn::meta::parsewhenattrsis empty: