Skip to content

Commit 5189ddb

Browse files
authored
refactor: cleanup union parsing (#4462)
1 parent 418afcc commit 5189ddb

3 files changed

Lines changed: 35 additions & 28 deletions

File tree

prqlc/prqlc-parser/src/lexer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ pub fn lex_token() -> impl Parser<char, Token, Error = Cheap<char>> {
108108
just("internal"),
109109
just("func"),
110110
just("import"),
111+
just("enum"),
111112
))
112113
.then_ignore(end_expr())
113114
.map(|x| x.to_string())

prqlc/prqlc-parser/src/types.rs

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -81,25 +81,32 @@ pub fn type_expr() -> impl Parser<TokenKind, Ty, Error = PError> {
8181
.map(TyKind::Tuple)
8282
.labelled("tuple");
8383

84-
let union_parenthesized = ident_part()
85-
.then_ignore(ctrl('='))
86-
.or_not()
87-
.then(nested_type_expr.clone())
88-
.padded_by(new_line().repeated())
89-
.separated_by(just(TokenKind::Or))
90-
.allow_trailing()
91-
.then_ignore(new_line().repeated())
92-
.delimited_by(ctrl('('), ctrl(')'))
93-
.recover_with(nested_delimiters(
94-
TokenKind::Control('('),
95-
TokenKind::Control(')'),
96-
[
97-
(TokenKind::Control('{'), TokenKind::Control('}')),
98-
(TokenKind::Control('('), TokenKind::Control(')')),
99-
(TokenKind::Control('['), TokenKind::Control(']')),
100-
],
101-
|_| vec![],
102-
))
84+
let enum_ = keyword("enum")
85+
.ignore_then(
86+
ident_part()
87+
.then(ctrl('=').ignore_then(nested_type_expr.clone()).or_not())
88+
.map(|(name, ty)| {
89+
(
90+
Some(name),
91+
ty.unwrap_or_else(|| Ty::new(TyKind::Tuple(vec![]))),
92+
)
93+
})
94+
.padded_by(new_line().repeated())
95+
.separated_by(ctrl(','))
96+
.allow_trailing()
97+
.then_ignore(new_line().repeated())
98+
.delimited_by(ctrl('{'), ctrl('}'))
99+
.recover_with(nested_delimiters(
100+
TokenKind::Control('{'),
101+
TokenKind::Control('}'),
102+
[
103+
(TokenKind::Control('{'), TokenKind::Control('}')),
104+
(TokenKind::Control('('), TokenKind::Control(')')),
105+
(TokenKind::Control('['), TokenKind::Control(']')),
106+
],
107+
|_| vec![],
108+
)),
109+
)
103110
.map(TyKind::Union)
104111
.labelled("union");
105112

@@ -120,7 +127,7 @@ pub fn type_expr() -> impl Parser<TokenKind, Ty, Error = PError> {
120127
.map(TyKind::Array)
121128
.labelled("array");
122129

123-
let term = choice((basic, ident, func, tuple, array, union_parenthesized))
130+
let term = choice((basic, ident, func, tuple, array, enum_))
124131
.map_with_span(into_ty)
125132
.boxed();
126133

prqlc/prqlc/tests/integration/resolving.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ fn resolve_types_01() {
5959
#[test]
6060
fn resolve_types_02() {
6161
assert_snapshot!(resolve(r#"
62-
type A = int || ()
62+
type A = int || {}
6363
"#).unwrap(), @r###"
64-
type A = int
64+
type A = int || {}
6565
"###)
6666
}
6767

@@ -78,16 +78,15 @@ fn resolve_types_03() {
7878
fn resolve_types_04() {
7979
assert_snapshot!(resolve(
8080
r#"
81-
type Status = (
82-
Paid = () ||
83-
Unpaid = float ||
84-
Canceled = {reason = text, cancelled_at = timestamp} ||
85-
)
81+
type Status = enum {
82+
Paid = {},
83+
Unpaid = float,
84+
Canceled = {reason = text, cancelled_at = timestamp},
85+
}
8686
"#,
8787
)
8888
.unwrap(), @r###"
8989
type Status = (
90-
Paid = () ||
9190
Unpaid = float ||
9291
{reason = text, cancelled_at = timestamp} ||
9392
)

0 commit comments

Comments
 (0)