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