aiken_lang/parser/expr/when/
mod.rs

1use chumsky::prelude::*;
2
3mod clause;
4mod guard;
5
6use crate::{
7    expr::UntypedExpr,
8    parser::{error::ParseError, token::Token},
9};
10pub use clause::parser as clause;
11pub use guard::parser as guard;
12
13pub fn parser(
14    expression: Recursive<'_, Token, UntypedExpr, ParseError>,
15) -> impl Parser<Token, UntypedExpr, Error = ParseError> + '_ {
16    just(Token::When)
17        // TODO: If subject is empty we should return ParseErrorType::ExpectedExpr,
18        .ignore_then(expression.clone().map(Box::new))
19        .then_ignore(just(Token::Is))
20        .then_ignore(just(Token::LeftBrace))
21        // TODO: If clauses are empty we should return ParseErrorType::NoCaseClause
22        .then(clause(expression).repeated())
23        .then_ignore(just(Token::RightBrace))
24        .map_with_span(|(subject, clauses), span| UntypedExpr::When {
25            location: span,
26            subject,
27            clauses,
28        })
29}
30
31#[cfg(test)]
32mod tests {
33    use crate::assert_expr;
34
35    #[test]
36    fn when_basic() {
37        assert_expr!(
38            r#"
39            when a is {
40              1 | 4 | 5 -> {
41                let amazing = 5
42                amazing
43              }
44              3 -> 9
45              _ -> 4
46            }
47            "#
48        );
49    }
50
51    #[test]
52    fn when_guard_deprecation() {
53        assert_expr!(
54            r#"
55            when a is {
56              2 if x > 1 -> 3
57              _ -> 1
58            }
59            "#
60        );
61    }
62}