use syn::{Token, parse::Parse};
use crate::parse::next_node_id;
use crate::pattern::Pattern;
#[derive(Debug, Clone)]
pub(crate) struct PatternMap {
pub node_id: usize,
pub span: proc_macro2::Span,
pub entries: Vec<(syn::Expr, Pattern)>,
pub rest: bool,
}
impl Parse for PatternMap {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let _: Token![#] = input.parse()?;
let span = input.span();
let content;
syn::braced!(content in input);
let (entries, rest) = parse_map_entries(&content)?;
Ok(PatternMap {
node_id: next_node_id(),
span,
entries,
rest,
})
}
}
fn parse_map_entries(
input: syn::parse::ParseStream,
) -> syn::Result<(Vec<(syn::Expr, Pattern)>, bool)> {
let mut entries = Vec::new();
let mut rest = false;
while !input.is_empty() {
if input.peek(Token![..]) {
let _: Token![..] = input.parse()?;
rest = true;
break;
}
let key: syn::Expr = input.parse()?;
let _: Token![:] = input.parse()?;
let value = input.parse()?;
entries.push((key, value));
if input.is_empty() {
break;
}
let _: Token![,] = input.parse()?;
if input.peek(Token![..]) {
let _: Token![..] = input.parse()?;
rest = true;
break;
}
}
Ok((entries, rest))
}