macro_rules! custom_keyword { ($ident:ident) => { ... }; }
Expand description
Define a type that supports parsing and printing a given identifier as if it were a keyword.
§Usage
As a convention, it is recommended that this macro be invoked within a
module called kw
or keyword
and that the resulting parser be invoked
with a kw::
or keyword::
prefix.
mod kw {
syn::custom_keyword!(whatever);
}
The generated syntax tree node supports the following operations just like any built-in keyword token.
-
Peeking —
input.peek(kw::whatever)
-
Parsing —
input.parse::<kw::whatever>()?
-
Printing —
quote!( ... #whatever_token ... )
-
Construction from a
Span
—let whatever_token = kw::whatever(sp)
-
Field access to its span —
let sp = whatever_token.span
§Example
This example parses input that looks like bool = true
or str = "value"
.
The key must be either the identifier bool
or the identifier str
. If
bool
, the value may be either true
or false
. If str
, the value may
be any string literal.
The symbols bool
and str
are not reserved keywords in Rust so these are
not considered keywords in the syn::token
module. Like any other
identifier that is not a keyword, these can be declared as custom keywords
by crates that need to use them as such.
use syn::{LitBool, LitStr, Result, Token};
use syn::parse::{Parse, ParseStream};
mod kw {
syn::custom_keyword!(bool);
syn::custom_keyword!(str);
}
enum Argument {
Bool {
bool_token: kw::bool,
eq_token: Token![=],
value: LitBool,
},
Str {
str_token: kw::str,
eq_token: Token![=],
value: LitStr,
},
}
impl Parse for Argument {
fn parse(input: ParseStream) -> Result<Self> {
let lookahead = input.lookahead1();
if lookahead.peek(kw::bool) {
Ok(Argument::Bool {
bool_token: input.parse::<kw::bool>()?,
eq_token: input.parse()?,
value: input.parse()?,
})
} else if lookahead.peek(kw::str) {
Ok(Argument::Str {
str_token: input.parse::<kw::str>()?,
eq_token: input.parse()?,
value: input.parse()?,
})
} else {
Err(lookahead.error())
}
}
}