Skip to main content

linkrs_query/parser/parsing/traversal_parser/
get_subgraph.rs

1use crate::parser::ast::stmt::*;
2use crate::parser::core::error::ParseError;
3use crate::parser::parsing::clause_parser::ClauseParser;
4use crate::parser::parsing::parse_context::ParseContext;
5use crate::parser::TokenKind;
6
7use super::TraversalParser;
8
9impl TraversalParser {
10    /// Analysis of the GET SUBGRAPH statement
11    pub fn parse_subgraph_statement(&mut self, ctx: &mut ParseContext) -> Result<Stmt, ParseError> {
12        let start_span = ctx.current_span();
13        ctx.expect_token(TokenKind::Get)?;
14
15        ctx.expect_token(TokenKind::Subgraph)?;
16
17        let with_prop = if ctx.match_token(TokenKind::With) {
18            ctx.expect_token(TokenKind::Prop)?;
19            true
20        } else {
21            false
22        };
23
24        let steps = if matches!(ctx.current_token().kind, TokenKind::IntegerLiteral(_)) {
25            let n = ctx.expect_integer_literal()?;
26            ctx.expect_token(TokenKind::Step)?;
27            Steps::Fixed(n as usize)
28        } else if ctx.match_token(TokenKind::Step) {
29            self.parse_steps(ctx)?
30        } else {
31            Steps::Fixed(1)
32        };
33
34        ctx.expect_token(TokenKind::From)?;
35        let from_span = ctx.current_span();
36        let from_clause = ctx.recover_clause(
37            |c| {
38                Ok(FromClause {
39                    span: c.current_span(),
40                    vertices: Vec::new(),
41                })
42            },
43            |c| {
44                let vertices = self.parse_expression_list(c)?;
45                Ok(FromClause {
46                    span: from_span,
47                    vertices,
48                })
49            },
50        )?;
51
52        let over = if ctx.match_token(TokenKind::Over) {
53            ctx.recover_clause(
54                |_| Ok(None),
55                |c| ClauseParser::new().parse_over_clause(c).map(Some),
56            )?
57        } else {
58            None
59        };
60
61        let where_clause = if ctx.match_token(TokenKind::Where) {
62            Some(ctx.recover_clause(Self::create_true_expression, |c| self.parse_expression(c))?)
63        } else {
64            Some(Self::create_true_expression(ctx)?)
65        };
66
67        let yield_clause = if ctx.match_token(TokenKind::Yield) {
68            ctx.recover_clause(
69                |_| Ok(None),
70                |c| ClauseParser::new().parse_yield_clause(c).map(Some),
71            )?
72        } else {
73            None
74        };
75
76        let span = ctx.span_since(start_span.start);
77
78        Ok(Stmt::Subgraph(SubgraphStmt {
79            span,
80            steps,
81            from: from_clause,
82            over,
83            where_clause,
84            yield_clause,
85            with_prop,
86        }))
87    }
88}