use proc_macro2::{TokenStream, TokenTree};
use quote::ToTokens;
use syn::{
Pat,
parse::{Parse, ParseStream, Parser},
};
use crate::{Error, ErrorPriority, Errors, Input, IntoTokens, PopFrom, grammar};
grammar! {
#[derive(Clone)]
pub struct Pattern {
syn: Pat,
}
}
impl PopFrom for Pattern {
fn pop_from(input: &mut Input, errors: &mut Errors) -> Result<Self, ()> {
fn parse(input: ParseStream) -> syn::Result<(Pattern, TokenStream)> {
Ok((
Pattern {
syn: Pat::parse_multi_with_leading_vert(input)?,
},
TokenStream::parse(input)?,
))
}
let error_span = input
.front_span()
.join(input.end)
.unwrap_or(input.front_span());
let tokens = input.tokens.drain(..).collect::<TokenStream>().into();
let (this, rest) = parse.parse2(tokens).map_err(|error| {
errors.push(Error::new(
ErrorPriority::GRAMMAR,
"Expected Expression except StructExpression.",
[error_span],
));
})?;
input.prepend(rest.into_iter().collect::<Vec<_>>());
Ok(this)
}
}
impl IntoTokens for Pattern {
fn into_tokens(self, root: &TokenStream, tokens: &mut impl Extend<TokenTree>) {
self.syn.into_token_stream().into_tokens(root, tokens);
}
}