mod binary_op;
mod concat_string;
mod conditional;
mod func_call;
mod list;
mod literal;
mod map;
mod mapper;
mod traversal;
mod trim_string;
mod type_guard;
mod unary_op;
mod variable;
use crate::err::*;
use crate::eval::*;
use crate::value::*;
use enum_dispatch::enum_dispatch;
pub use binary_op::{BinaryOpExpr, BinaryOperator, OpError};
pub use concat_string::ConcatStringExpr;
pub use conditional::ConditionalExpr;
pub use func_call::FuncCallExpr;
pub use list::ListExpr;
pub use literal::LiteralExpr;
pub use map::{MapExpr, MapKey};
pub use mapper::{MapperExpr, Output};
pub use traversal::TraversalExpr;
pub use trim_string::TrimStringExpr;
pub use type_guard::TypeGuardExpr;
pub use unary_op::{UnaryOpExpr, UnaryOperator};
pub use variable::VariableExpr;
#[enum_dispatch(Expr)]
#[derive(Debug, Clone)]
pub enum Expression {
Literal(LiteralExpr),
List(ListExpr),
Map(MapExpr),
Variable(VariableExpr),
BinaryOp(BinaryOpExpr),
UnaryOp(UnaryOpExpr),
ConcatString(ConcatStringExpr),
Conditional(ConditionalExpr),
FuncCall(FuncCallExpr),
Traversal(TraversalExpr),
Mapper(MapperExpr),
TypeGuard(TypeGuardExpr),
TrimString(TrimStringExpr),
}
impl Expression {
pub fn literal(literal: impl Into<LiteralExpr>) -> Self {
Expression::Literal(literal.into())
}
pub fn list(list: impl Into<ListExpr>) -> Self {
Expression::List(list.into())
}
pub fn map(map: impl Into<MapExpr>) -> Self {
Expression::Map(map.into())
}
pub fn variable(variable: impl Into<VariableExpr>) -> Self {
Expression::Variable(variable.into())
}
pub fn binary_op(binary_op: impl Into<BinaryOpExpr>) -> Self {
Expression::BinaryOp(binary_op.into())
}
pub fn unary_op(unary_op: impl Into<UnaryOpExpr>) -> Self {
Expression::UnaryOp(unary_op.into())
}
pub fn concat_string(concat_string: impl Into<ConcatStringExpr>) -> Self {
Expression::ConcatString(concat_string.into())
}
pub fn conditional(conditional: impl Into<ConditionalExpr>) -> Self {
Expression::Conditional(conditional.into())
}
pub fn func_call(func_call: impl Into<FuncCallExpr>) -> Self {
Expression::FuncCall(func_call.into())
}
pub fn traversal(traversal: impl Into<TraversalExpr>) -> Self {
Expression::Traversal(traversal.into())
}
pub fn mapper(mapper: impl Into<MapperExpr>) -> Self {
Expression::Mapper(mapper.into())
}
pub fn type_guard(type_guard: impl Into<TypeGuardExpr>) -> Self {
Expression::TypeGuard(type_guard.into())
}
pub fn trim_string(trim_string: impl Into<TrimStringExpr>) -> Self {
Expression::TrimString(trim_string.into())
}
pub fn as_string_literal(&self) -> Option<&str> {
match self {
Expression::Literal(LiteralExpr {
value: Value::String(s),
}) => Some(s.as_str()),
_ => None,
}
}
}
impl<T> From<T> for Expression
where
T: Into<Value>,
{
fn from(value: T) -> Self {
Expression::Literal(LiteralExpr {
value: value.into(),
})
}
}
pub trait ExprEvaluator {
fn ensure_resolved(&self, indices: Vec<Index>) -> Result<(), ErrorKind>;
fn get_value(&self, target: Index) -> Result<Value, ErrorKind>;
fn traverse(
&self,
expression: Index,
name: &Indexer,
) -> Result<Option<ValueOrReference>, ErrorKind>;
fn resolve_variable(&self, index: Index, name: String) -> Result<ValueOrReference, ErrorKind>;
fn create(&mut self, expression: Expression) -> Index;
fn clone_with_context(&mut self, index: Index, context: Index) -> Index;
}
#[enum_dispatch]
pub trait Expr {
fn resolve(
&self,
index: Index,
evaluation: &mut dyn ExprEvaluator,
) -> Result<ValueOrReference, ErrorKind>;
fn traverse(
&self,
_evaluation: &dyn ExprEvaluator,
_expression: Index,
_name: &Indexer,
) -> Result<Option<ValueOrReference>, ErrorKind> {
Ok(None)
}
}