Skip to main content

xrust/parser/combinators/
many.rs

1use crate::item::Node;
2use crate::parser::{ParseError, ParseInput, StaticState};
3use qualname::{NamespacePrefix, NamespaceUri};
4
5pub fn many0<'a, P, R, N: Node, L>(
6    parser: P,
7) -> impl Fn(ParseInput<'a, N>, &mut StaticState<L>) -> Result<(ParseInput<'a, N>, Vec<R>), ParseError>
8where
9    P: Fn(ParseInput<'a, N>, &mut StaticState<L>) -> Result<(ParseInput<'a, N>, R), ParseError>,
10    L: FnMut(&NamespacePrefix) -> Result<NamespaceUri, ParseError>,
11{
12    move |mut input, ss| {
13        let mut result = Vec::new();
14
15        loop {
16            match parser(input.clone(), ss) {
17                Ok((input2, next_item)) => {
18                    result.push(next_item);
19                    input = input2;
20                }
21                Err(ParseError::Combinator(_)) | Err(ParseError::NotWellFormed(_)) => break,
22                Err(e) => return Err(e),
23            }
24        }
25
26        Ok((input, result))
27    }
28}
29
30/// This is a special combinator, it will reset namespaces on the parser state between iterations
31/// It is only intended for use when parsing the children of an element node.
32pub fn many0nsreset<'a, P, R, N: Node, L>(
33    parser: P,
34) -> impl Fn(ParseInput<'a, N>, &mut StaticState<L>) -> Result<(ParseInput<'a, N>, Vec<R>), ParseError>
35where
36    P: Fn(ParseInput<'a, N>, &mut StaticState<L>) -> Result<(ParseInput<'a, N>, R), ParseError>,
37    L: FnMut(&NamespacePrefix) -> Result<NamespaceUri, ParseError>,
38{
39    //TODO ERROR IF ANY ERROR OTHER THAN COMBINATOR RETURNED.
40
41    move |(mut input, mut state), ss| {
42        let mut result = Vec::new();
43        let namespaces = state.in_scope_namespaces.clone();
44
45        while let Ok(((input2, state2), next_item)) = parser((input, state.clone()), ss) {
46            result.push(next_item);
47            input = input2;
48            state = state2;
49            state.in_scope_namespaces = namespaces.clone();
50        }
51
52        Ok(((input, state), result))
53    }
54}
55
56pub fn many1<'a, P, R, N: Node, L>(
57    parser: P,
58) -> impl Fn(ParseInput<'a, N>, &mut StaticState<L>) -> Result<(ParseInput<'a, N>, Vec<R>), ParseError>
59where
60    P: Fn(ParseInput<'a, N>, &mut StaticState<L>) -> Result<(ParseInput<'a, N>, R), ParseError>,
61    L: FnMut(&NamespacePrefix) -> Result<NamespaceUri, ParseError>,
62{
63    //TODO ERROR IF ANY ERROR OTHER THAN COMBINATOR RETURNED.
64    move |mut input, ss| {
65        let mut result = Vec::new();
66
67        match parser(input, ss) {
68            Err(err) => Err(err),
69            Ok((input1, result1)) => {
70                input = input1;
71                result.push(result1);
72                while let Ok((input2, next_item)) = parser(input.clone(), ss) {
73                    input = input2;
74                    result.push(next_item);
75                }
76                Ok((input, result))
77            }
78        }
79    }
80}