yarte_parser/
stmt_local.rs1use proc_macro2::TokenStream;
2use quote::{quote, ToTokens};
3use syn::{
4 parse::{Parse, ParseStream},
5 punctuated::Punctuated,
6 token::Semi,
7 Expr, Local, Pat, PatOr, PatType, Result, Token, Type,
8};
9
10#[derive(Debug, PartialEq)]
11pub struct StmtLocal {
12 pub let_token: Token![let],
13 pub pat: Pat,
14 pub init: Option<(Token![=], Box<Expr>)>,
15}
16
17impl Parse for StmtLocal {
19 fn parse(input: ParseStream) -> Result<Self> {
20 Ok(StmtLocal {
21 let_token: input.parse()?,
22 pat: {
23 let leading_vert: Option<Token![|]> = input.parse()?;
24 let mut pat: Pat = input.parse()?;
25 if leading_vert.is_some()
26 || input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=])
27 {
28 let mut cases = Punctuated::new();
29 cases.push_value(pat);
30 while input.peek(Token![|])
31 && !input.peek(Token![||])
32 && !input.peek(Token![|=])
33 {
34 let punct = input.parse()?;
35 cases.push_punct(punct);
36 let pat: Pat = input.parse()?;
37 cases.push_value(pat);
38 }
39 pat = Pat::Or(PatOr {
40 attrs: Vec::new(),
41 leading_vert,
42 cases,
43 });
44 }
45 if input.peek(Token![:]) {
46 let colon_token: Token![:] = input.parse()?;
47 let ty: Type = input.parse()?;
48 pat = Pat::Type(PatType {
49 attrs: Vec::new(),
50 pat: Box::new(pat),
51 colon_token,
52 ty: Box::new(ty),
53 });
54 }
55 pat
56 },
57 init: {
58 if input.peek(Token![=]) {
59 let eq_token: Token![=] = input.parse()?;
60 let init: Expr = input.parse()?;
61 Some((eq_token, Box::new(init)))
62 } else {
63 None
64 }
65 },
66 })
67 }
68}
69
70impl ToTokens for StmtLocal {
71 fn to_tokens(&self, tokens: &mut TokenStream) {
72 let StmtLocal {
73 let_token,
74 pat,
75 init,
76 } = self;
77 if let Some((eq, init)) = init {
78 tokens.extend(quote!(#let_token #pat #eq #init));
79 } else {
80 tokens.extend(quote!(#let_token #pat));
81 }
82 }
83}
84
85impl Into<Local> for StmtLocal {
87 fn into(self) -> Local {
88 Local {
89 let_token: self.let_token,
90 attrs: Vec::new(),
91 pat: self.pat,
92 init: self.init,
93 semi_token: Semi::default(),
94 }
95 }
96}
97
98impl From<Local> for StmtLocal {
99 fn from(local: Local) -> Self {
100 StmtLocal {
101 let_token: local.let_token,
102 pat: local.pat,
103 init: local.init,
104 }
105 }
106}
107
108impl Into<crate::Local> for StmtLocal {
109 fn into(self) -> crate::Local {
110 crate::Local(self.into())
111 }
112}