use syn::{Token, parse::Parse, punctuated::Punctuated};
use crate::parse::next_node_id;
use crate::pattern::FieldAssertion;
#[derive(Debug, Clone)]
pub(crate) struct PatternStruct {
pub node_id: usize,
pub path: Option<syn::Path>,
pub fields: Punctuated<FieldAssertion, Token![,]>,
pub rest: bool,
}
impl Parse for PatternStruct {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let node_id = next_node_id();
let path = if input.peek(Token![_]) {
let _: Token![_] = input.parse()?;
None } else if input.peek(syn::token::Brace) {
None } else {
Some(input.parse::<syn::Path>()?)
};
let content;
syn::braced!(content in input);
let mut fields = Punctuated::new();
let mut rest = false;
while !content.is_empty() {
if content.peek(Token![..]) {
let _: Token![..] = content.parse()?;
rest = true;
break;
}
fields.push_value(content.parse()?);
if content.is_empty() {
break;
}
let comma: Token![,] = content.parse()?;
fields.push_punct(comma);
if content.peek(Token![..]) {
let _: Token![..] = content.parse()?;
rest = true;
break;
}
}
if path.is_none() {
rest = true;
}
Ok(PatternStruct {
node_id,
path,
fields,
rest,
})
}
}