aiken_lang/parser/expr/when/
clause.rs1use super::guard;
2use crate::{
3 ast,
4 expr::UntypedExpr,
5 parser::{error::ParseError, pattern, token::Token},
6};
7use chumsky::prelude::*;
8use vec1::vec1;
9
10pub fn parser(
11 expression: Recursive<'_, Token, UntypedExpr, ParseError>,
12) -> impl Parser<Token, ast::UntypedClause, Error = ParseError> + '_ {
13 pattern()
14 .then(
15 choice((
16 just(Token::Vbar),
17 just(Token::VbarVbar),
18 just(Token::Or),
19 just(Token::Comma),
20 ))
21 .ignore_then(pattern())
22 .repeated()
23 .or_not(),
24 )
25 .then(choice((just(Token::If)
26 .ignore_then(guard())
27 .or_not()
28 .then_ignore(just(Token::RArrow)),)))
29 .then(expression)
31 .validate(
32 |(((pattern, alternative_patterns_opt), guard), then), span, emit| {
33 if guard.is_some() {
34 emit(ParseError::deprecated_when_clause_guard(span));
35 }
36
37 (pattern, alternative_patterns_opt, then)
38 },
39 )
40 .map_with_span(|(pattern, alternative_patterns_opt, then), span| {
41 let mut patterns = vec1![pattern];
42 patterns.append(&mut alternative_patterns_opt.unwrap_or_default());
43 ast::UntypedClause {
44 location: span,
45 patterns,
46 then,
47 }
48 })
49}
50
51#[cfg(test)]
52mod tests {
53 use crate::assert_expr;
54
55 #[test]
56 fn when_clause_todo() {
57 assert_expr!(
58 r#"
59 when val is {
60 Bar1{..} -> True
61 Bar2{..} -> todo @"unimplemented"
62 }
63 "#
64 );
65 }
66
67 #[test]
68 fn when_clause_solo_error() {
69 assert_expr!(
70 r#"
71 when val is {
72 Bar1{..} -> fail
73 }
74 "#
75 );
76 }
77
78 #[test]
79 fn when_clause_double_todo() {
80 assert_expr!(
81 r#"
82 when val is {
83 Bar1{..} -> todo
84 Bar2{..} -> todo
85 }
86 "#
87 );
88 }
89
90 #[test]
91 fn when_clause_alternative() {
92 assert_expr!(
93 r#"
94 when val is {
95 Bar1{..} | Bar2{..} -> todo
96 Bar3{..} || Bar4{..} -> todo
97 Bar5{..} or Bar6{..} -> todo
98 Bar5{..}, Bar6{..} -> todo
99 }
100 "#
101 );
102 }
103}