Skip to main content

xrust/parser/xpath/
compare.rs

1//! Functions that produce comparisons.
2
3use crate::item::Node;
4use crate::parser::combinators::map::map;
5use crate::parser::combinators::opt::opt;
6use crate::parser::combinators::pair::pair;
7use crate::parser::combinators::tag::anytag;
8use crate::parser::combinators::tuple::tuple3;
9use crate::parser::combinators::whitespace::xpwhitespace;
10use crate::parser::xpath::strings::stringconcat_expr;
11use crate::parser::{ParseError, ParseInput, StaticState};
12use crate::transform::Transform;
13use crate::value::Operator;
14use qualname::{NamespacePrefix, NamespaceUri};
15
16// ComparisonExpr ::= StringConcatExpr ( (ValueComp | GeneralComp | NodeComp) StringConcatExpr)?
17pub(crate) fn comparison_expr<'a, N: Node + 'a, L>() -> Box<
18    dyn Fn(
19            ParseInput<'a, N>,
20            &mut StaticState<L>,
21        ) -> Result<(ParseInput<'a, N>, Transform<N>), ParseError>
22        + 'a,
23>
24where
25    L: FnMut(&NamespacePrefix) -> Result<NamespaceUri, ParseError> + 'a,
26{
27    Box::new(map(
28        pair(
29            stringconcat_expr::<N, L>(),
30            opt(pair(
31                tuple3(
32                    xpwhitespace(),
33                    anytag(vec![
34                        "=", "!=", "<", "<=", "<<", ">", ">=", ">>", "eq", "ne", "lt", "le", "gt",
35                        "ge", "is",
36                    ]),
37                    xpwhitespace(),
38                ),
39                stringconcat_expr::<N, L>(),
40            )),
41        ),
42        |(v, o)| match o {
43            None => v,
44            Some(((_, b, _), t)) => {
45                match b.as_str() {
46                    "=" | "!=" | "<" | "<=" | ">" | ">=" => {
47                        Transform::GeneralComparison(Operator::from(b), Box::new(v), Box::new(t))
48                    }
49                    "eq" | "ne" | "lt" | "le" | "gt" | "ge" | "is" | "<<" | ">>" => {
50                        Transform::ValueComparison(Operator::from(b), Box::new(v), Box::new(t))
51                    }
52                    _ => Transform::Empty, // error
53                }
54            }
55        },
56    ))
57}