diff options
Diffstat (limited to 'syn-mid/src/pat.rs')
-rw-r--r-- | syn-mid/src/pat.rs | 413 |
1 files changed, 0 insertions, 413 deletions
diff --git a/syn-mid/src/pat.rs b/syn-mid/src/pat.rs deleted file mode 100644 index 8f95381..0000000 --- a/syn-mid/src/pat.rs +++ /dev/null @@ -1,413 +0,0 @@ -use syn::{punctuated::Punctuated, token, Attribute, Ident, Member, Path, Token, Type}; - -ast_enum_of_structs! { - /// A pattern in a local binding, function signature, match expression, or - /// various other places. - /// - /// # Syntax tree enum - /// - /// This type is a [syntax tree enum]. - /// - /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums - pub enum Pat { - /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`. - Ident(PatIdent), - - /// A path pattern like `Color::Red`. - Path(PatPath), - - /// A reference pattern: `&mut var`. - Reference(PatReference), - - /// A struct or struct variant pattern: `Variant { x, y, .. }`. - Struct(PatStruct), - - /// A tuple pattern: `(a, b)`. - Tuple(PatTuple), - - /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`. - TupleStruct(PatTupleStruct), - - /// A type ascription pattern: `foo: f64`. - Type(PatType), - - /// A pattern that matches any value: `_`. - Wild(PatWild), - - #[doc(hidden)] - __Nonexhaustive, - } -} - -ast_struct! { - /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`. - pub struct PatIdent { - pub attrs: Vec<Attribute>, - pub by_ref: Option<Token![ref]>, - pub mutability: Option<Token![mut]>, - pub ident: Ident, - } -} - -ast_struct! { - /// A path pattern like `Color::Red`. - pub struct PatPath { - pub attrs: Vec<Attribute>, - pub path: Path, - } -} - -ast_struct! { - /// A reference pattern: `&mut var`. - pub struct PatReference { - pub attrs: Vec<Attribute>, - pub and_token: Token![&], - pub mutability: Option<Token![mut]>, - pub pat: Box<Pat>, - } -} - -ast_struct! { - /// A struct or struct variant pattern: `Variant { x, y, .. }`. - pub struct PatStruct { - pub attrs: Vec<Attribute>, - pub path: Path, - pub brace_token: token::Brace, - pub fields: Punctuated<FieldPat, Token![,]>, - pub dot2_token: Option<Token![..]>, - } -} - -ast_struct! { - /// A tuple pattern: `(a, b)`. - pub struct PatTuple { - pub attrs: Vec<Attribute>, - pub paren_token: token::Paren, - pub elems: Punctuated<Pat, Token![,]>, - } -} - -ast_struct! { - /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`. - pub struct PatTupleStruct { - pub attrs: Vec<Attribute>, - pub path: Path, - pub pat: PatTuple, - } -} - -ast_struct! { - /// A type ascription pattern: `foo: f64`. - pub struct PatType { - pub attrs: Vec<Attribute>, - pub pat: Box<Pat>, - pub colon_token: Token![:], - pub ty: Box<Type>, - } -} - -ast_struct! { - /// A pattern that matches any value: `_`. - pub struct PatWild { - pub attrs: Vec<Attribute>, - pub underscore_token: Token![_], - } -} - -ast_struct! { - /// A single field in a struct pattern. - /// - /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` are treated - /// the same as `x: x, y: ref y, z: ref mut z` but there is no colon token. - pub struct FieldPat { - pub attrs: Vec<Attribute>, - pub member: Member, - pub colon_token: Option<Token![:]>, - pub pat: Box<Pat>, - } -} - -mod parsing { - use syn::{ - braced, - ext::IdentExt, - parenthesized, - parse::{Parse, ParseStream, Result}, - punctuated::Punctuated, - token, Ident, Member, Path, Token, - }; - - use crate::path; - - use super::{ - FieldPat, Pat, PatIdent, PatPath, PatReference, PatStruct, PatTuple, PatTupleStruct, - PatWild, - }; - - impl Parse for Pat { - fn parse(input: ParseStream<'_>) -> Result<Self> { - let lookahead = input.lookahead1(); - if lookahead.peek(Ident) - && ({ - input.peek2(Token![::]) - || input.peek2(token::Brace) - || input.peek2(token::Paren) - }) - || input.peek(Token![self]) && input.peek2(Token![::]) - || lookahead.peek(Token![::]) - || lookahead.peek(Token![<]) - || input.peek(Token![Self]) - || input.peek(Token![super]) - || input.peek(Token![extern]) - || input.peek(Token![crate]) - { - pat_path_or_struct(input) - } else if lookahead.peek(Token![_]) { - input.call(pat_wild).map(Pat::Wild) - } else if lookahead.peek(Token![ref]) - || lookahead.peek(Token![mut]) - || input.peek(Token![self]) - || input.peek(Ident) - { - input.call(pat_ident).map(Pat::Ident) - } else if lookahead.peek(Token![&]) { - input.call(pat_reference).map(Pat::Reference) - } else if lookahead.peek(token::Paren) { - input.call(pat_tuple).map(Pat::Tuple) - } else { - Err(lookahead.error()) - } - } - } - - fn pat_path_or_struct(input: ParseStream<'_>) -> Result<Pat> { - let path = path::parse_path(input)?; - - if input.peek(token::Brace) { - pat_struct(input, path).map(Pat::Struct) - } else if input.peek(token::Paren) { - pat_tuple_struct(input, path).map(Pat::TupleStruct) - } else { - Ok(Pat::Path(PatPath { - attrs: Vec::new(), - path, - })) - } - } - - fn pat_wild(input: ParseStream<'_>) -> Result<PatWild> { - Ok(PatWild { - attrs: Vec::new(), - underscore_token: input.parse()?, - }) - } - - fn pat_ident(input: ParseStream<'_>) -> Result<PatIdent> { - Ok(PatIdent { - attrs: Vec::new(), - by_ref: input.parse()?, - mutability: input.parse()?, - ident: input.call(Ident::parse_any)?, - }) - } - - fn pat_tuple_struct(input: ParseStream<'_>, path: Path) -> Result<PatTupleStruct> { - Ok(PatTupleStruct { - attrs: Vec::new(), - path, - pat: input.call(pat_tuple)?, - }) - } - - fn pat_struct(input: ParseStream<'_>, path: Path) -> Result<PatStruct> { - let content; - let brace_token = braced!(content in input); - - let mut fields = Punctuated::new(); - while !content.is_empty() && !content.peek(Token![..]) { - let value = content.call(field_pat)?; - fields.push_value(value); - if !content.peek(Token![,]) { - break; - } - let punct: Token![,] = content.parse()?; - fields.push_punct(punct); - } - - let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) { - Some(content.parse()?) - } else { - None - }; - - Ok(PatStruct { - attrs: Vec::new(), - path, - brace_token, - fields, - dot2_token, - }) - } - - fn field_pat(input: ParseStream<'_>) -> Result<FieldPat> { - let boxed: Option<Token![box]> = input.parse()?; - let by_ref: Option<Token![ref]> = input.parse()?; - let mutability: Option<Token![mut]> = input.parse()?; - let member: Member = input.parse()?; - - if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:]) - || is_unnamed(&member) - { - return Ok(FieldPat { - attrs: Vec::new(), - member, - colon_token: input.parse()?, - pat: input.parse()?, - }); - } - - let ident = match member { - Member::Named(ident) => ident, - Member::Unnamed(_) => unreachable!(), - }; - - let pat = Pat::Ident(PatIdent { - attrs: Vec::new(), - by_ref, - mutability, - ident: ident.clone(), - }); - - Ok(FieldPat { - member: Member::Named(ident), - pat: Box::new(pat), - attrs: Vec::new(), - colon_token: None, - }) - } - - fn pat_tuple(input: ParseStream<'_>) -> Result<PatTuple> { - let content; - let paren_token = parenthesized!(content in input); - - let mut elems = Punctuated::new(); - while !content.is_empty() { - let value: Pat = content.parse()?; - elems.push_value(value); - if content.is_empty() { - break; - } - let punct = content.parse()?; - elems.push_punct(punct); - } - - Ok(PatTuple { - attrs: Vec::new(), - paren_token, - elems, - }) - } - - fn pat_reference(input: ParseStream<'_>) -> Result<PatReference> { - Ok(PatReference { - attrs: Vec::new(), - and_token: input.parse()?, - mutability: input.parse()?, - pat: input.parse()?, - }) - } - - fn is_unnamed(member: &Member) -> bool { - match member { - Member::Named(_) => false, - Member::Unnamed(_) => true, - } - } -} - -mod printing { - use proc_macro2::TokenStream; - use quote::{ToTokens, TokenStreamExt}; - use syn::Token; - - use super::{ - FieldPat, PatIdent, PatPath, PatReference, PatStruct, PatTuple, PatTupleStruct, PatType, - PatWild, - }; - - impl ToTokens for PatWild { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.underscore_token.to_tokens(tokens); - } - } - - impl ToTokens for PatIdent { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.by_ref.to_tokens(tokens); - self.mutability.to_tokens(tokens); - self.ident.to_tokens(tokens); - } - } - - impl ToTokens for PatStruct { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.path.to_tokens(tokens); - self.brace_token.surround(tokens, |tokens| { - self.fields.to_tokens(tokens); - // NOTE: We need a comma before the dot2 token if it is present. - if !self.fields.empty_or_trailing() && self.dot2_token.is_some() { - <Token![,]>::default().to_tokens(tokens); - } - self.dot2_token.to_tokens(tokens); - }); - } - } - - impl ToTokens for PatTupleStruct { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.path.to_tokens(tokens); - self.pat.to_tokens(tokens); - } - } - - impl ToTokens for PatType { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append_all(&self.attrs); - self.pat.to_tokens(tokens); - self.colon_token.to_tokens(tokens); - self.ty.to_tokens(tokens); - } - } - - impl ToTokens for PatPath { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.path.to_tokens(tokens) - } - } - - impl ToTokens for PatTuple { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.paren_token.surround(tokens, |tokens| { - self.elems.to_tokens(tokens); - }); - } - } - - impl ToTokens for PatReference { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.and_token.to_tokens(tokens); - self.mutability.to_tokens(tokens); - self.pat.to_tokens(tokens); - } - } - - impl ToTokens for FieldPat { - fn to_tokens(&self, tokens: &mut TokenStream) { - if let Some(colon_token) = &self.colon_token { - self.member.to_tokens(tokens); - colon_token.to_tokens(tokens); - } - self.pat.to_tokens(tokens); - } - } -} |