linkrs_query/parser/parsing/
session_parser.rs1use crate::parser::ast::stmt::*;
7use crate::parser::core::error::{ParseError, ParseErrorKind};
8use crate::parser::parsing::expr_parser::parse_expression_with_context;
9use crate::parser::parsing::parse_context::ParseContext;
10use crate::parser::TokenKind;
11
12pub struct SessionParser;
14
15impl Default for SessionParser {
16 fn default() -> Self {
17 Self
18 }
19}
20
21impl SessionParser {
22 pub fn new() -> Self {
23 Self
24 }
25
26 pub fn parse_let_statement(&mut self, ctx: &mut ParseContext) -> Result<Stmt, ParseError> {
33 let start_span = ctx.current_span();
34 ctx.expect_token(TokenKind::Let)?;
35
36 let _ = ctx.match_token(TokenKind::Dollar);
37
38 let name = match ctx.expect_identifier() {
39 Ok(name) => name,
40 Err(_) => {
41 let pos = ctx.current_position();
42 let display_name = ctx.current_token().lexeme.clone();
43 return Err(ParseError::new(
44 ParseErrorKind::SyntaxError,
45 format!("Invalid session variable name '{}'", display_name),
46 pos,
47 ));
48 }
49 };
50 let valid = !name.is_empty()
51 && name
52 .chars()
53 .next()
54 .is_some_and(|c| c.is_ascii_alphabetic() || c == '_')
55 && name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_');
56 if !valid {
57 let pos = ctx.current_position();
58 return Err(ParseError::new(
59 ParseErrorKind::SyntaxError,
60 format!("Invalid session variable name '{}'", name),
61 pos,
62 ));
63 }
64
65 if !ctx.check_token(TokenKind::Assign) {
66 let pos = ctx.current_position();
67 return Err(ParseError::new(
68 ParseErrorKind::SyntaxError,
69 "LET requires an assignment: LET $name = expr".to_string(),
70 pos,
71 ));
72 }
73 ctx.expect_token(TokenKind::Assign)?;
74
75 let expression = parse_expression_with_context(ctx, ctx.expression_context_clone())?;
76 let span = ctx.span_since(start_span.start);
77
78 Ok(Stmt::AssignVariable(AssignVariableStmt {
79 span,
80 name,
81 expression,
82 }))
83 }
84
85 pub fn parse_kill_statement(&mut self, ctx: &mut ParseContext) -> Result<Stmt, ParseError> {
87 let start_span = ctx.current_span();
88 ctx.expect_token(TokenKind::Kill)?;
89 ctx.expect_token(TokenKind::Query)?;
90
91 let session_id = ctx.expect_integer_literal()?;
92 ctx.expect_token(TokenKind::Comma)?;
93 let plan_id = ctx.expect_integer_literal()?;
94
95 let span = ctx.span_since(start_span.start);
96
97 Ok(Stmt::KillQuery(KillQueryStmt {
98 span,
99 session_id,
100 plan_id,
101 }))
102 }
103}