#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Axis {
Child,
Descendant,
Parent,
SelfNode,
DescendantOrSelf,
Ancestor,
AncestorOrSelf,
FollowingSibling,
PrecedingSibling,
Following,
Preceding,
Attribute,
Namespace,
}
#[derive(Debug, Clone, PartialEq)]
pub enum NodeTest {
Any,
Name(String),
QName {
prefix: String,
local: String,
},
Text,
Node,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Predicate {
Comparison {
left: Box<Expr>,
op: ComparisonOp,
right: Box<Expr>,
},
And(Box<Predicate>, Box<Predicate>),
Or(Box<Predicate>, Box<Predicate>),
Not(Box<Predicate>),
Position(usize),
Expr(Box<Expr>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ComparisonOp {
Equal,
NotEqual,
LessThan,
LessOrEqual,
GreaterThan,
GreaterOrEqual,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Expr {
Path(PathExpr),
String(String),
Number(f64),
Variable(String),
Function {
name: String,
args: Vec<Expr>,
},
Union(Vec<PathExpr>),
Add(Box<Expr>, Box<Expr>),
Subtract(Box<Expr>, Box<Expr>),
Multiply(Box<Expr>, Box<Expr>),
Divide(Box<Expr>, Box<Expr>),
Modulo(Box<Expr>, Box<Expr>),
Negate(Box<Expr>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct PathExpr {
pub absolute: bool,
pub steps: Vec<Step>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Step {
pub axis: Axis,
pub node_test: NodeTest,
pub predicates: Vec<Predicate>,
}
impl Step {
pub fn child(name: &str) -> Self {
Self {
axis: Axis::Child,
node_test: Self::parse_name(name),
predicates: Vec::new(),
}
}
pub fn descendant_or_self_any() -> Self {
Self {
axis: Axis::DescendantOrSelf,
node_test: NodeTest::Node,
predicates: Vec::new(),
}
}
fn parse_name(name: &str) -> NodeTest {
if name == "*" {
NodeTest::Any
} else if let Some((prefix, local)) = name.split_once(':') {
NodeTest::QName {
prefix: prefix.to_string(),
local: local.to_string(),
}
} else {
NodeTest::Name(name.to_string())
}
}
}