Skip to main content

shape_ast/parser/queries/
parsing.rs

1//! Main query parsing implementation
2
3use crate::error::{Result, ShapeError};
4use crate::parser::{Rule, pair_location};
5use pest::iterators::Pair;
6
7use crate::ast::Query;
8
9use super::alert::parse_alert_query;
10use super::with::parse_with_query;
11
12/// Parse a query
13///
14/// Dispatches to the appropriate query parser based on the query type.
15pub fn parse_query(pair: Pair<Rule>) -> Result<Query> {
16    let pair_loc = pair_location(&pair);
17    let inner = pair
18        .into_inner()
19        .next()
20        .ok_or_else(|| ShapeError::ParseError {
21            message: "expected query content".to_string(),
22            location: Some(
23                pair_loc
24                    .clone()
25                    .with_hint("provide a query like 'alert' or 'with'"),
26            ),
27        })?;
28
29    match inner.as_rule() {
30        Rule::with_query => Ok(Query::With(parse_with_query(inner)?)),
31        Rule::alert_query => Ok(Query::Alert(parse_alert_query(inner)?)),
32        _ => Err(ShapeError::ParseError {
33            message: format!("unexpected query type: {:?}", inner.as_rule()),
34            location: Some(pair_location(&inner)),
35        }),
36    }
37}
38
39/// Parse an inner query (used in subqueries and WITH clauses)
40///
41/// Inner queries don't have the outer query wrapper, so we dispatch directly.
42pub fn parse_inner_query(pair: Pair<Rule>) -> Result<Query> {
43    match pair.as_rule() {
44        Rule::inner_query => {
45            let inner = pair
46                .into_inner()
47                .next()
48                .ok_or_else(|| ShapeError::ParseError {
49                    message: "expected inner query content".to_string(),
50                    location: None,
51                })?;
52            parse_inner_query(inner)
53        }
54        Rule::alert_query => Ok(Query::Alert(parse_alert_query(pair)?)),
55        _ => Err(ShapeError::ParseError {
56            message: format!("unexpected inner query type: {:?}", pair.as_rule()),
57            location: Some(pair_location(&pair)),
58        }),
59    }
60}