I am building a macro parser with syn and need to check if a ParseStream
is one of several keywords. The code currently looks similar to this:
mod kw {
syn::custom_keyword!(a);
syn::custom_keyword!(b);
syn::custom_keyword!(c);
}
enum MyKeywordEnum {
A(kw::a),
B(kw::b),
C(kw::c),
}
impl syn::parse::Parse for MyKeywordEnum {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
Ok(if let Ok(ret) = input.parse::<kw::a>() {
Self::A(ret)
} else if let Ok(ret) = input.parse::<kw::b>() {
Self::B(ret)
} else if let Ok(ret) = input.parse::<kw::c>() {
Self::C(ret)
} else {
abort!(input.span(), "Couldn't parse primitive type"); // Via #[proc_macro_error]
})
}
}
Option::Some
or Result::Ok
?ParseStream::parse
statically compiles to the specific impl Parse
type, I can't use match
, right?As far as I know, there is not. You could create a macro to do this, or you could use the Result
combinator functions to make things a little prettier:
impl syn::parse::Parse for MyKeywordEnum {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
input.parse::<kw::a>().map(Self::A)
.or_else(|_| input.parse::<kw::b>().map(Self::B))
.or_else(|_| input.parse::<kw::c>().map(Self::C))
.or_else(|_| abort!(input.span(), "Couldn't parse primitive type"))
}
}