// The previous examples all used an exclusive range, MIN..MAX. Now make it work
// for an inclusive range MIN..=MAX that includes the upper range bound!
use seq::seq;
seq!(N in 16..=20 {
enum E {
#(
Variant~N,
)*
}
});
fn main() {
let e = E::Variant16;
let desc = match e {
E::Variant16 => "min",
E::Variant17 | E::Variant18 | E::Variant19 => "in between",
E::Variant20 => "max",
};
assert_eq!(desc, "min");
}
這一關主要是增加了a..=b
中的相等,也就是對end
的調整。
解析的時候我們需要預讀一下。
pub(crate) fn parse_range(input: &syn::parse::ParseStream) -> syn::Result<(usize, usize)> {
let begin = input.parse::<syn::LitInt>()?.base10_parse()?;
let _ = input.parse::<syn::Token!(..)>()?;
let mut incude_grater = false;
if input.peek(syn::Token!(=)) {
input.parse::<syn::Token!(=)>()?;
incude_grater = true;
}
let mut end = input.parse::<syn::LitInt>()?.base10_parse()?;
if incude_grater {
end += 1;
}
syn::Result::Ok((begin, end))
}
其中使用peek
方法,我們可以預讀一下而不消耗token
,十分方便。
這裡parse
方法對應的調整即可
impl syn::parse::Parse for crate::parser::SeqParser {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let variable_ident = input.parse::<syn::Ident>()?;
let _ = input.parse::<syn::Token!(in)>()?;
let (begin, end) = crate::solution7::parse_range(&input)?;
let body_buf;
let _ = syn::braced!(body_buf in input);
let body = body_buf.parse::<proc_macro2::TokenStream>()?;
syn::Result::Ok(crate::parser::SeqParser {
variable_ident,
begin,
end,
body,
})
}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結