xrust/parser/xpath/
logic.rs1use crate::item::Node;
4use crate::parser::combinators::list::separated_list1;
5use crate::parser::combinators::map::map;
6use crate::parser::combinators::tag::tag;
7use crate::parser::combinators::tuple::tuple3;
8use crate::parser::combinators::whitespace::xpwhitespace;
9use crate::parser::xpath::compare::comparison_expr;
10use crate::parser::{ParseError, ParseInput};
11use crate::transform::Transform;
12
13pub(crate) fn or_expr<'a, N: Node + 'a>(
15) -> Box<dyn Fn(ParseInput<N>) -> Result<(ParseInput<N>, Transform<N>), ParseError> + 'a> {
16 Box::new(map(
17 separated_list1(
18 map(tuple3(xpwhitespace(), tag("or"), xpwhitespace()), |_| ()),
19 and_expr::<N>(),
20 ),
21 |mut v| {
22 if v.len() == 1 {
23 v.pop().unwrap()
24 } else {
25 Transform::Or(v)
26 }
27 },
28 ))
29}
30
31fn and_expr<'a, N: Node + 'a>(
33) -> Box<dyn Fn(ParseInput<N>) -> Result<(ParseInput<N>, Transform<N>), ParseError> + 'a> {
34 Box::new(map(
35 separated_list1(
36 map(tuple3(xpwhitespace(), tag("and"), xpwhitespace()), |_| ()),
37 comparison_expr::<N>(),
38 ),
39 |mut v| {
40 if v.len() == 1 {
41 v.pop().unwrap()
42 } else {
43 Transform::And(v)
44 }
45 },
46 ))
47}