#[derive(Debug, Clone)]
pub enum Expr {
Null,
Bool(bool),
Int(i64),
Float(f64),
Str(String),
FString(Vec<FStringPart>),
Root,
Current,
Ident(String),
Chain(Box<Expr>, Vec<Step>),
BinOp(Box<Expr>, BinOp, Box<Expr>),
UnaryNeg(Box<Expr>),
Not(Box<Expr>),
Kind {
expr: Box<Expr>,
ty: KindType,
negate: bool,
},
Coalesce(Box<Expr>, Box<Expr>),
Object(Vec<ObjField>),
Array(Vec<ArrayElem>),
Pipeline {
base: Box<Expr>,
steps: Vec<PipeStep>,
},
ListComp {
expr: Box<Expr>,
vars: Vec<String>,
iter: Box<Expr>,
cond: Option<Box<Expr>>,
},
DictComp {
key: Box<Expr>,
val: Box<Expr>,
vars: Vec<String>,
iter: Box<Expr>,
cond: Option<Box<Expr>>,
},
SetComp {
expr: Box<Expr>,
vars: Vec<String>,
iter: Box<Expr>,
cond: Option<Box<Expr>>,
},
GenComp {
expr: Box<Expr>,
vars: Vec<String>,
iter: Box<Expr>,
cond: Option<Box<Expr>>,
},
Lambda {
params: Vec<String>,
body: Box<Expr>,
},
Let {
name: String,
init: Box<Expr>,
body: Box<Expr>,
},
IfElse {
cond: Box<Expr>,
then_: Box<Expr>,
else_: Box<Expr>,
},
Try {
body: Box<Expr>,
default: Box<Expr>,
},
GlobalCall {
name: String,
args: Vec<Arg>,
},
Cast {
expr: Box<Expr>,
ty: CastType,
},
Patch {
root: Box<Expr>,
ops: Vec<PatchOp>,
},
UpdateBatch {
root: Box<Expr>,
selector: Vec<PathStep>,
ops: Vec<PatchOp>,
},
DeleteMark,
Match {
scrutinee: Box<Expr>,
arms: Vec<MatchArm>,
},
}
#[derive(Debug, Clone)]
pub struct MatchArm {
pub pat: Pat,
pub guard: Option<Expr>,
pub body: Expr,
}
#[derive(Debug, Clone)]
pub enum Pat {
Wild,
Lit(PatLit),
Bind(String),
Or(Vec<Pat>),
Obj {
fields: Vec<(String, Pat)>,
rest: Option<Option<String>>,
},
Arr {
elems: Vec<Pat>,
rest: Option<Option<String>>,
},
Kind {
name: Option<String>,
kind: KindType,
},
Range {
lo: f64,
hi: f64,
inclusive: bool,
},
}
#[derive(Debug, Clone)]
pub enum PatLit {
Null,
Bool(bool),
Int(i64),
Float(f64),
Str(String),
}
#[derive(Debug, Clone)]
pub struct PatchOp {
pub path: Vec<PathStep>,
pub val: Expr,
pub cond: Option<Expr>,
}
#[derive(Debug, Clone)]
pub enum PathStep {
Field(String),
Index(i64),
DynIndex(Expr),
Wildcard,
WildcardFilter(Box<Expr>),
Descendant(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CastType {
Int,
Float,
Number,
Str,
Bool,
Array,
Object,
Null,
}
#[derive(Debug, Clone)]
pub enum PipeStep {
Forward(Expr),
Bind(BindTarget),
}
#[derive(Debug, Clone)]
pub enum BindTarget {
Name(String),
Obj {
fields: Vec<String>,
rest: Option<String>,
},
Arr(Vec<String>),
}
#[derive(Debug, Clone)]
pub enum FStringPart {
Lit(String),
Interp { expr: Expr, fmt: Option<FmtSpec> },
}
#[derive(Debug, Clone)]
pub enum FmtSpec {
Spec(String),
Pipe(String),
}
#[derive(Debug, Clone)]
pub enum ArrayElem {
Expr(Expr),
Spread(Expr),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum QuantifierKind {
First,
One,
}
#[derive(Debug, Clone)]
pub enum Step {
Field(String),
OptField(String),
Descendant(String),
DescendAll,
Index(i64),
DynIndex(Box<Expr>),
Slice(Option<i64>, Option<i64>, Option<i64>),
Wildcard,
Method(String, Vec<Arg>),
OptMethod(String, Vec<Arg>),
InlineFilter(Box<Expr>),
Quantifier(QuantifierKind),
DeepMatch {
arms: Vec<MatchArm>,
early_stop: bool,
},
}
#[derive(Debug, Clone)]
pub enum Arg {
Pos(Expr),
Named(String, Expr),
}
#[derive(Debug, Clone)]
pub enum ObjField {
Kv {
key: String,
val: Expr,
optional: bool,
cond: Option<Expr>,
},
Short(String),
Dynamic { key: Expr, val: Expr },
Spread(Expr),
SpreadDeep(Expr),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinOp {
Add,
Sub,
Mul,
Div,
Mod,
Eq,
Neq,
Lt,
Lte,
Gt,
Gte,
Fuzzy,
And,
Or,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KindType {
Null,
Bool,
Number,
Str,
Array,
Object,
}
impl Expr {
pub fn maybe_chain(self, steps: Vec<Step>) -> Self {
if steps.is_empty() {
self
} else {
Expr::Chain(Box::new(self), steps)
}
}
}