Skip to main content

oxml/xpath/
ast.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2// Copyright (c) 2026 oxml. All rights reserved.
3
4//! The `XPath` expression tree.
5
6use alloc::boxed::Box;
7use alloc::string::String;
8use alloc::vec::Vec;
9
10/// Which direction and which nodes a step selects.
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum Axis {
13    /// `child::` — the default axis.
14    Child,
15    /// `descendant::`
16    Descendant,
17    /// `descendant-or-self::` — the `//` shorthand.
18    DescendantOrSelf,
19    /// `parent::`
20    Parent,
21    /// `ancestor::`
22    Ancestor,
23    /// `ancestor-or-self::`
24    AncestorOrSelf,
25    /// `self::` — the `.` shorthand.
26    SelfAxis,
27    /// `attribute::` — the `@` shorthand.
28    Attribute,
29    /// `following-sibling::`
30    FollowingSibling,
31    /// `preceding-sibling::`
32    PrecedingSibling,
33}
34
35/// What a step matches once the axis has produced candidates.
36#[derive(Debug, Clone, PartialEq, Eq)]
37pub enum NodeTest {
38    /// `*` — any element (or any attribute on the attribute axis).
39    Wildcard,
40    /// A local name, matched ignoring namespace.
41    Name(String),
42    /// `text()`
43    Text,
44    /// `comment()`
45    Comment,
46    /// `node()` — anything at all.
47    Any,
48}
49
50/// One location step: an axis, a test, and zero or more predicates.
51#[derive(Debug, Clone, PartialEq)]
52pub struct Step {
53    /// The axis to walk.
54    pub axis: Axis,
55    /// The test applied to each candidate.
56    pub test: NodeTest,
57    /// Predicates, applied left to right.
58    pub predicates: Vec<Expr>,
59}
60
61/// An `XPath` expression.
62#[derive(Debug, Clone, PartialEq)]
63pub enum Expr {
64    /// A location path. `absolute` means it started with `/`.
65    Path {
66        /// Whether the path starts at the document root.
67        absolute: bool,
68        /// The steps, in order.
69        steps: Vec<Step>,
70    },
71    /// A literal string.
72    Literal(String),
73    /// A literal number.
74    Number(f64),
75    /// A binary operation.
76    Binary {
77        /// The operator.
78        op: BinaryOp,
79        /// Left operand.
80        lhs: Box<Expr>,
81        /// Right operand.
82        rhs: Box<Expr>,
83    },
84    /// A function call.
85    Function {
86        /// The function's name.
87        name: String,
88        /// Its arguments.
89        args: Vec<Expr>,
90    },
91    /// Unary negation.
92    Negate(Box<Expr>),
93}
94
95/// A binary operator.
96#[derive(Debug, Clone, Copy, PartialEq, Eq)]
97pub enum BinaryOp {
98    /// `=`
99    Eq,
100    /// `!=`
101    Ne,
102    /// `<`
103    Lt,
104    /// `<=`
105    Le,
106    /// `>`
107    Gt,
108    /// `>=`
109    Ge,
110    /// `and`
111    And,
112    /// `or`
113    Or,
114    /// `+`
115    Add,
116    /// `-`
117    Sub,
118    /// `*`
119    Mul,
120    /// `div`
121    Div,
122    /// `mod`
123    Mod,
124    /// `|` — node-set union.
125    Union,
126}