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
use crate::ast;
use crate::{Parse, ParseError, Parser, Spanned, ToTokens};
#[derive(Debug, Clone, PartialEq, Eq, ToTokens, Spanned)]
pub struct ExprMatch {
#[rune(iter)]
pub attributes: Vec<ast::Attribute>,
pub match_: T![match],
pub expr: ast::Expr,
pub open: T!['{'],
pub branches: Vec<(ExprMatchBranch, Option<T![,]>)>,
pub close: T!['}'],
}
impl ExprMatch {
pub fn parse_with_attributes(
parser: &mut Parser<'_>,
attributes: Vec<ast::Attribute>,
) -> Result<Self, ParseError> {
let match_ = parser.parse()?;
let expr = ast::Expr::parse_without_eager_brace(parser)?;
let open = parser.parse()?;
let mut branches = Vec::new();
while !parser.peek::<ast::CloseBrace>()? {
let branch = parser.parse::<ExprMatchBranch>()?;
let comma = parser.parse::<Option<T![,]>>()?;
let is_end = ast::utils::is_block_end(&branch.body, comma.as_ref());
branches.push((branch, comma));
if is_end {
break;
}
}
let close = parser.parse()?;
Ok(ExprMatch {
attributes,
match_,
expr,
open,
branches,
close,
})
}
}
expr_parse!(Match, ExprMatch, "match expression");
#[derive(Debug, Clone, PartialEq, Eq, ToTokens, Parse, Spanned)]
pub struct ExprMatchBranch {
pub pat: ast::Pat,
pub condition: Option<(T![if], ast::Expr)>,
pub rocket: T![=>],
pub body: ast::Expr,
}