eventql_parser/
lib.rs

1//! EventQL parser library for parsing event sourcing query language.
2//!
3//! This library provides a complete lexer and parser for EventQL (EQL), a query language
4//! designed for event sourcing systems. It allows you to parse EQL query strings into
5//! an abstract syntax tree (AST) that can be analyzed or executed.
6mod ast;
7mod error;
8mod lexer;
9mod parser;
10#[cfg(test)]
11mod tests;
12mod token;
13
14use crate::error::{Error, LexerError};
15use crate::prelude::{parse, tokenize};
16pub use ast::*;
17use nom::Err;
18
19/// Convenience module that re-exports all public types and functions.
20///
21/// This module provides a single import point for all the library's public API,
22/// including AST types, error types, lexer, parser, and token types.
23pub mod prelude {
24    pub use super::ast::*;
25    pub use super::error::*;
26    pub use super::lexer::*;
27    pub use super::parser::*;
28    pub use super::token::*;
29}
30
31pub type Result<A> = std::result::Result<A, error::Error>;
32
33/// Parse an EventQL query string into an abstract syntax tree.
34///
35/// This is the main entry point for parsing EventQL queries. It performs both
36/// lexical analysis (tokenization) and syntactic analysis (parsing) in a single call.
37/// # Examples
38///
39/// ```
40/// use eventql_parser::parse_query;
41///
42/// // Parse a simple query
43/// let query = parse_query("FROM e IN events WHERE e.id == 1 PROJECT INTO e").unwrap();
44/// assert!(query.predicate.is_some());
45///
46/// // Parse with multiple clauses
47/// let complex = parse_query(
48///     "FROM e IN events \
49///      WHERE e.price > 100 \
50///      ORDER BY e.timestamp DESC \
51///      TOP 10 \
52///      PROJECT INTO {id: e.id, price: e.price}"
53/// ).unwrap();
54/// assert!(complex.order_by.is_some());
55/// assert!(complex.limit.is_some());
56///
57/// // Handle errors
58/// match parse_query("FROM e IN events WHERE") {
59///     Ok(_) => println!("Parsed successfully"),
60///     Err(e) => println!("Parse error: {}", e),
61/// }
62/// ```
63pub fn parse_query(input: &str) -> Result<Query> {
64    let tokens = tokenize(input).map_err(|e| match e {
65        Err::Incomplete(_) => Error::Lexer(LexerError::IncompleteInput),
66        Err::Error(x) => Error::Lexer(LexerError::InvalidSymbol(
67            x.input.location_line(),
68            x.input.get_column() as u32,
69        )),
70        Err::Failure(x) => Error::Lexer(LexerError::InvalidSymbol(
71            x.input.location_line(),
72            x.input.get_column() as u32,
73        )),
74    })?;
75
76    parse(tokens.as_slice()).map_err(Error::Parser)
77}