1use crate::{
2 ParseResult, Parser, ParserExt, ParserHandle, ParserNoValue, ParserOutput, ParserRegistry,
3};
4
5pub mod shorthand {
6 use super::*;
7
8 pub fn list(item: ParserHandle, delimiter: ParserHandle, permissive: bool) -> ParserHandle {
9 ListParser::new(item, delimiter, permissive).into_handle()
10 }
11
12 pub fn list_inv(item: ParserHandle, delimiter: ParserHandle, permissive: bool) -> ParserHandle {
13 ListParser::new(item, delimiter, permissive)
14 .ignore_no_value(true)
15 .into_handle()
16 }
17}
18
19#[derive(Clone)]
20pub struct ListParser {
21 item: ParserHandle,
22 delimiter: ParserHandle,
23 permissive: bool,
24 ignore_no_value: bool,
25}
26
27impl ListParser {
28 pub fn new(item: ParserHandle, delimiter: ParserHandle, permissive: bool) -> Self {
29 Self {
30 item,
31 delimiter,
32 permissive,
33 ignore_no_value: false,
34 }
35 }
36
37 pub fn ignore_no_value(mut self, ignore: bool) -> Self {
38 self.ignore_no_value = ignore;
39 self
40 }
41}
42
43impl Parser for ListParser {
44 fn parse<'a>(&self, registry: &ParserRegistry, mut input: &'a str) -> ParseResult<'a> {
45 let mut result = vec![];
46 if let Ok((new_input, value)) = self.item.parse(registry, input) {
47 input = new_input;
48 if !self.ignore_no_value || !value.is::<ParserNoValue>() {
49 result.push(value);
50 }
51 while let Ok((new_input, _)) = self.delimiter.parse(registry, input) {
52 match self.item.parse(registry, new_input) {
53 Ok((new_input, value)) => {
54 input = new_input;
55 if !self.ignore_no_value || !value.is::<ParserNoValue>() {
56 result.push(value);
57 }
58 }
59 Err(error) => {
60 if self.permissive {
61 break;
62 } else {
63 return Err(error);
64 }
65 }
66 }
67 }
68 }
69 Ok((input, ParserOutput::new(result).ok().unwrap()))
70 }
71
72 fn extend(&self, parser: ParserHandle) {
73 self.item.extend(parser);
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use crate::{
80 ParserOutput, ParserRegistry,
81 list::ListParser,
82 shorthand::{alt, list, lit, ows},
83 };
84
85 fn is_async<T: Send + Sync>() {}
86
87 #[test]
88 fn test_list() {
89 is_async::<ListParser>();
90
91 let registry = ParserRegistry::default();
92 let sentence = list(alt([lit("foo"), lit("bar")]), ows(), true);
93 let (rest, _) = sentence.parse(®istry, "").unwrap();
94 assert_eq!(rest, "");
95 let (rest, result) = sentence.parse(®istry, "foobar foozee").unwrap();
96 assert_eq!(rest, "zee");
97 let result = result.consume::<Vec<ParserOutput>>().ok().unwrap();
98 assert_eq!(result.len(), 3);
99 assert_eq!(result[0].read::<String>().unwrap().as_str(), "foo");
100 assert_eq!(result[1].read::<String>().unwrap().as_str(), "bar");
101 assert_eq!(result[2].read::<String>().unwrap().as_str(), "foo");
102 }
103}