xee_xpath_ast/
pattern_transform.rs

1use crate::pattern;
2
3struct Transformer<S, T, E, F>
4where
5    F: FnMut(&S) -> Result<T, E>,
6{
7    _s: std::marker::PhantomData<S>,
8    _t: std::marker::PhantomData<T>,
9    _e: std::marker::PhantomData<E>,
10    transform: F,
11}
12
13impl<S, T, E, F> Transformer<S, T, E, F>
14where
15    F: FnMut(&S) -> Result<T, E>,
16{
17    fn new(transform: F) -> Self {
18        Self {
19            _s: std::marker::PhantomData,
20            _t: std::marker::PhantomData,
21            _e: std::marker::PhantomData,
22            transform,
23        }
24    }
25
26    fn pattern(&mut self, pattern: &pattern::Pattern<S>) -> Result<pattern::Pattern<T>, E> {
27        Ok(match pattern {
28            pattern::Pattern::Predicate(predicate_pattern) => {
29                pattern::Pattern::Predicate(self.predicate_pattern(predicate_pattern)?)
30            }
31            pattern::Pattern::Expr(expr_pattern) => {
32                pattern::Pattern::Expr(self.expr_pattern(expr_pattern)?)
33            }
34        })
35    }
36
37    fn predicates(&mut self, predicates: &[S]) -> Result<Vec<T>, E> {
38        predicates
39            .iter()
40            .map(|predicate| (self.transform)(predicate))
41            .collect::<Result<Vec<_>, _>>()
42    }
43
44    fn predicate_pattern(
45        &mut self,
46        predicate_pattern: &pattern::PredicatePattern<S>,
47    ) -> Result<pattern::PredicatePattern<T>, E> {
48        Ok(pattern::PredicatePattern {
49            predicates: self.predicates(&predicate_pattern.predicates)?,
50        })
51    }
52
53    fn expr_pattern(
54        &mut self,
55        expr_pattern: &pattern::ExprPattern<S>,
56    ) -> Result<pattern::ExprPattern<T>, E> {
57        Ok(match expr_pattern {
58            pattern::ExprPattern::Path(path_expr) => {
59                pattern::ExprPattern::Path(self.path_expr(path_expr)?)
60            }
61            pattern::ExprPattern::BinaryExpr(binary_expr) => self.binary_expr(binary_expr)?,
62        })
63    }
64
65    fn path_expr(&mut self, path_expr: &pattern::PathExpr<S>) -> Result<pattern::PathExpr<T>, E> {
66        Ok(pattern::PathExpr {
67            root: self.path_root(&path_expr.root)?,
68            steps: path_expr
69                .steps
70                .iter()
71                .map(|step| self.step_expr(step))
72                .collect::<Result<Vec<_>, _>>()?,
73        })
74    }
75
76    fn path_root(&mut self, path_root: &pattern::PathRoot<S>) -> Result<pattern::PathRoot<T>, E> {
77        Ok(match path_root {
78            pattern::PathRoot::Rooted { root, predicates } => pattern::PathRoot::Rooted {
79                root: root.clone(),
80                predicates: self.predicates(predicates)?,
81            },
82            pattern::PathRoot::AbsoluteSlash => pattern::PathRoot::AbsoluteSlash,
83            pattern::PathRoot::AbsoluteDoubleSlash => pattern::PathRoot::AbsoluteDoubleSlash,
84            pattern::PathRoot::Relative => pattern::PathRoot::Relative,
85        })
86    }
87
88    fn step_expr(&mut self, step_expr: &pattern::StepExpr<S>) -> Result<pattern::StepExpr<T>, E> {
89        Ok(match step_expr {
90            pattern::StepExpr::PostfixExpr(postfix_expr) => {
91                pattern::StepExpr::PostfixExpr(self.postfix_expr(postfix_expr)?)
92            }
93            pattern::StepExpr::AxisStep(axis_step) => {
94                pattern::StepExpr::AxisStep(self.axis_step(axis_step)?)
95            }
96        })
97    }
98
99    fn postfix_expr(
100        &mut self,
101        postfix_expr: &pattern::PostfixExpr<S>,
102    ) -> Result<pattern::PostfixExpr<T>, E> {
103        Ok(pattern::PostfixExpr {
104            expr: self.expr_pattern(&postfix_expr.expr)?,
105            predicates: self.predicates(&postfix_expr.predicates)?,
106        })
107    }
108
109    fn axis_step(&mut self, axis_step: &pattern::AxisStep<S>) -> Result<pattern::AxisStep<T>, E> {
110        Ok(pattern::AxisStep {
111            forward: axis_step.forward,
112            node_test: axis_step.node_test.clone(),
113            predicates: self.predicates(&axis_step.predicates)?,
114        })
115    }
116
117    fn binary_expr(
118        &mut self,
119        binary_expr: &pattern::BinaryExpr<S>,
120    ) -> Result<pattern::ExprPattern<T>, E> {
121        Ok(pattern::ExprPattern::BinaryExpr(pattern::BinaryExpr {
122            operator: binary_expr.operator,
123            left: Box::new(self.expr_pattern(&binary_expr.left)?),
124            right: Box::new(self.expr_pattern(&binary_expr.right)?),
125        }))
126    }
127}
128
129pub fn transform_pattern<S, T, E, F>(
130    pattern: &pattern::Pattern<S>,
131    transform: F,
132) -> Result<pattern::Pattern<T>, E>
133where
134    F: FnMut(&S) -> Result<T, E>,
135{
136    Transformer::new(transform).pattern(pattern)
137}