pub mod ast;
pub mod engine;
pub mod eval;
pub mod expr;
pub mod graph;
pub mod parser;
pub mod vm;
pub mod analysis;
pub mod schema;
pub mod plan;
pub mod cfg;
pub mod ssa;
#[cfg(test)]
mod tests;
#[cfg(test)]
mod examples;
use std::cell::RefCell;
use std::sync::Arc;
use serde_json::Value;
pub use engine::Engine;
pub use eval::EvalError;
pub use eval::{Method, MethodRegistry};
pub use expr::Expr;
pub use graph::Graph;
pub use parser::ParseError;
pub use vm::{VM, Compiler, Program};
pub trait JetroSchema {
const EXPRS: &'static [(&'static str, &'static str)];
fn exprs() -> &'static [(&'static str, &'static str)];
fn names() -> &'static [&'static str];
}
#[derive(Debug)]
pub enum Error {
Parse(ParseError),
Eval(EvalError),
}
pub type Result<T> = std::result::Result<T, Error>;
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::Parse(e) => write!(f, "{}", e),
Error::Eval(e) => write!(f, "{}", e),
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::Parse(e) => Some(e),
Error::Eval(_) => None,
}
}
}
impl From<ParseError> for Error { fn from(e: ParseError) -> Self { Error::Parse(e) } }
impl From<EvalError> for Error { fn from(e: EvalError) -> Self { Error::Eval(e) } }
pub fn query(expr: &str, doc: &Value) -> Result<Value> {
let ast = parser::parse(expr)?;
Ok(eval::evaluate(&ast, doc)?)
}
pub fn query_with(expr: &str, doc: &Value, registry: Arc<MethodRegistry>) -> Result<Value> {
let ast = parser::parse(expr)?;
Ok(eval::evaluate_with(&ast, doc, registry)?)
}
thread_local! {
static THREAD_VM: RefCell<VM> = RefCell::new(VM::new());
}
pub struct Jetro {
document: Value,
}
impl Jetro {
pub fn new(document: Value) -> Self {
Self { document }
}
pub fn collect<S: AsRef<str>>(&self, expr: S) -> std::result::Result<Value, EvalError> {
let expr = expr.as_ref();
THREAD_VM.with(|cell| match cell.try_borrow_mut() {
Ok(mut vm) => vm.run_str(expr, &self.document),
Err(_) => VM::new().run_str(expr, &self.document),
})
}
}
impl From<Value> for Jetro {
fn from(v: Value) -> Self {
Self::new(v)
}
}