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