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}