intuicio_parser/
one_or_more.rs1use crate::{ParseResult, Parser, ParserExt, ParserHandle, ParserOutput, ParserRegistry};
2
3pub mod shorthand {
4 use super::*;
5
6 pub fn oom(parser: ParserHandle) -> ParserHandle {
7 OneOrMoreParser::new(parser).into_handle()
8 }
9}
10
11#[derive(Clone)]
12pub struct OneOrMoreParser(ParserHandle);
13
14impl OneOrMoreParser {
15 pub fn new(parser: ParserHandle) -> Self {
16 Self(parser)
17 }
18}
19
20impl Parser for OneOrMoreParser {
21 fn parse<'a>(&self, registry: &ParserRegistry, mut input: &'a str) -> ParseResult<'a> {
22 let (new_input, value) = self.0.parse(registry, input)?;
23 input = new_input;
24 let mut result = vec![value];
25 while let Ok((new_input, value)) = self.0.parse(registry, input) {
26 result.push(value);
27 input = new_input;
28 }
29 Ok((input, ParserOutput::new(result).ok().unwrap()))
30 }
31
32 fn extend(&self, parser: ParserHandle) {
33 self.0.extend(parser);
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use crate::{
40 one_or_more::OneOrMoreParser,
41 shorthand::{lit, oom},
42 ParserOutput, ParserRegistry,
43 };
44
45 fn is_async<T: Send + Sync>() {}
46
47 #[test]
48 fn test_one_or_more() {
49 is_async::<OneOrMoreParser>();
50
51 let registry = ParserRegistry::default();
52 let sentence = oom(lit("foo"));
53 let (rest, result) = sentence.parse(®istry, "foofoofoo").unwrap();
54 assert_eq!(rest, "");
55 assert_eq!(result.consume::<Vec<ParserOutput>>().ok().unwrap().len(), 3);
56 assert_eq!(
57 format!("{}", sentence.parse(®istry, " asd ").err().unwrap()),
58 "Expected 'foo'"
59 );
60 }
61}