#[derive(Debug, Clone, PartialEq)]
pub enum Index {
Number(i64),
Wildcard,
Slice { start: Option<i64>, end: Option<i64> },
}
#[derive(Debug, Clone, PartialEq)]
pub enum Builtin {
Keys,
Values,
Length,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Segment {
pub key: Option<String>,
pub indices: Vec<Index>,
pub recursive: bool,
pub builtin: Option<Builtin>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Selector {
pub segments: Vec<Segment>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum CompareOp {
Eq,
Ne,
Gt,
Lt,
Gte,
Lte,
Match,
}
#[derive(Debug, Clone, PartialEq)]
pub enum LogicOp {
And,
Or,
}
#[derive(Debug, Clone, PartialEq)]
pub enum LiteralValue {
String(String),
Number(f64),
Bool(bool),
Null,
}
impl LiteralValue {
pub fn to_json_value(&self) -> serde_json::Value {
match self {
LiteralValue::String(s) => serde_json::Value::String(s.clone()),
LiteralValue::Number(n) => {
if n.fract() == 0.0 && *n >= i64::MIN as f64 && *n <= i64::MAX as f64 {
serde_json::Value::Number((*n as i64).into())
} else {
serde_json::Number::from_f64(*n)
.map(serde_json::Value::Number)
.unwrap_or(serde_json::Value::Null)
}
}
LiteralValue::Bool(b) => serde_json::Value::Bool(*b),
LiteralValue::Null => serde_json::Value::Null,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Condition {
pub path: Selector,
pub op: CompareOp,
pub value: LiteralValue,
}
#[derive(Debug, Clone, PartialEq)]
pub enum FilterExpr {
Condition(Condition),
Truthy(Selector),
And(Box<FilterExpr>, Box<FilterExpr>),
Or(Box<FilterExpr>, Box<FilterExpr>),
Not(Box<FilterExpr>),
}
#[derive(Debug, Clone, PartialEq)]
pub enum PipeStage {
Path(Selector),
Builtin(Builtin),
Select(FilterExpr),
Set { path: Selector, value: LiteralValue },
Del(Selector),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Pipeline {
pub stages: Vec<PipeStage>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Expression {
pub pipelines: Vec<Pipeline>,
}