1use super::{parse_token, DocComment, Expr, Ident, Lookahead, Parse, ParseResult, Peek};
2use crate::lexer::{Lexer, Token};
3use serde::Serialize;
4
5#[derive(Debug, Clone, Serialize)]
7#[serde(rename_all = "camelCase")]
8pub struct LetStatement<'a> {
9 pub docs: Vec<DocComment<'a>>,
11 pub id: Ident<'a>,
13 pub expr: Expr<'a>,
15}
16
17impl<'a> Parse<'a> for LetStatement<'a> {
18 fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
19 let docs = Parse::parse(lexer)?;
20 parse_token(lexer, Token::LetKeyword)?;
21 let id = Parse::parse(lexer)?;
22 parse_token(lexer, Token::Equals)?;
23 let expr = Parse::parse(lexer)?;
24 parse_token(lexer, Token::Semicolon)?;
25 Ok(Self { docs, id, expr })
26 }
27}
28
29impl Peek for LetStatement<'_> {
30 fn peek(lookahead: &mut Lookahead) -> bool {
31 lookahead.peek(Token::LetKeyword)
32 }
33}
34
35#[cfg(test)]
36mod test {
37 use crate::ast::test::roundtrip;
38
39 #[test]
40 fn let_statement_roundtrip() {
41 roundtrip(
42 "package foo:bar; let x= y;",
43 "package foo:bar;\n\nlet x = y;\n",
44 )
45 .unwrap();
46 roundtrip(
47 "package foo:bar; let x =y.x.z;",
48 "package foo:bar;\n\nlet x = y.x.z;\n",
49 )
50 .unwrap();
51 roundtrip(
52 "package foo:bar; let x=y[\"x\"][\"z\"];",
53 "package foo:bar;\n\nlet x = y[\"x\"][\"z\"];\n",
54 )
55 .unwrap();
56 roundtrip(
57 "package foo:bar; let x = foo[\"bar\"].baz[\"qux\"];",
58 "package foo:bar;\n\nlet x = foo[\"bar\"].baz[\"qux\"];\n",
59 )
60 .unwrap();
61
62 roundtrip(
63 "package foo:bar; let x = (y);",
64 "package foo:bar;\n\nlet x = (y);\n",
65 )
66 .unwrap();
67
68 roundtrip(
69 "package foo:bar; let x = new foo:bar {};",
70 "package foo:bar;\n\nlet x = new foo:bar {};\n",
71 )
72 .unwrap();
73
74 roundtrip(
75 "package foo:bar; let x = new foo:bar { foo, \"bar\": (new baz:qux {...}), \"baz\": foo[\"baz\"].qux };",
76 "package foo:bar;\n\nlet x = new foo:bar {\n foo,\n \"bar\": (new baz:qux { ... }),\n \"baz\": foo[\"baz\"].qux,\n};\n",
77 )
78 .unwrap();
79
80 roundtrip(
81 "package foo:bar; let x = new foo:bar { foo, ...i, bar: baz, ...i2, ...,};",
82 "package foo:bar;\n\nlet x = new foo:bar {\n foo,\n ...i,\n bar: baz,\n ...i2,\n ...\n};\n",
83 )
84 .unwrap();
85 }
86}