use serde_json::Value;
use std::sync::Arc;
#[derive(Debug, Clone, PartialEq)]
pub struct IfBranch {
pub cond: Option<Expr>,
pub body: Vec<Node>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct MacroParam {
pub name: String,
pub default: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct MacroDef {
pub name: String,
pub params: Vec<MacroParam>,
pub body: Vec<Node>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ForVars {
Single(String),
Multi(Vec<String>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct SwitchCase {
pub cond: Expr,
pub body: Vec<Node>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Node {
Root(Vec<Node>),
Text(Arc<str>),
Output(Vec<Expr>),
If { branches: Vec<IfBranch> },
For {
vars: ForVars,
iter: Expr,
body: Vec<Node>,
else_body: Option<Vec<Node>>,
},
Set {
targets: Vec<String>,
value: Option<Expr>,
body: Option<Vec<Node>>,
},
Include {
template: Expr,
ignore_missing: bool,
with_context: Option<bool>,
},
Switch {
expr: Expr,
cases: Vec<SwitchCase>,
default_body: Option<Vec<Node>>,
},
Extends { parent: Expr },
Block { name: String, body: Vec<Node> },
MacroDef(MacroDef),
Import {
template: Expr,
alias: String,
with_context: Option<bool>,
},
FromImport {
template: Expr,
names: Vec<(String, Option<String>)>,
with_context: Option<bool>,
},
FilterBlock {
name: String,
args: Vec<Expr>,
body: Vec<Node>,
},
CallBlock {
caller_params: Vec<MacroParam>,
callee: Expr,
body: Vec<Node>,
},
ExtensionTag {
extension_name: String,
tag: String,
args: String,
body: Option<Vec<Node>>,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CompareOp {
Eq,
StrictEq,
Ne,
StrictNe,
Lt,
Gt,
Le,
Ge,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinOp {
Add,
Sub,
Mul,
Div,
FloorDiv,
Mod,
Pow,
Concat,
And,
Or,
In,
Is,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnaryOp {
Not,
Neg,
Pos,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Expr {
Literal(Value),
Variable(String),
GetAttr {
base: Box<Expr>,
attr: String,
},
GetItem {
base: Box<Expr>,
index: Box<Expr>,
},
Slice {
start: Option<Box<Expr>>,
stop: Option<Box<Expr>>,
step: Option<Box<Expr>>,
},
Call {
callee: Box<Expr>,
args: Vec<Expr>,
kwargs: Vec<(String, Expr)>,
},
Filter {
name: String,
input: Box<Expr>,
args: Vec<Expr>,
},
List(Vec<Expr>),
Dict(Vec<(Expr, Expr)>),
InlineIf {
cond: Box<Expr>,
then_expr: Box<Expr>,
else_expr: Option<Box<Expr>>,
},
Unary {
op: UnaryOp,
expr: Box<Expr>,
},
Binary {
op: BinOp,
left: Box<Expr>,
right: Box<Expr>,
},
Compare {
head: Box<Expr>,
rest: Vec<(CompareOp, Expr)>,
},
RegexLiteral {
pattern: String,
flags: String,
},
}