1use crate::{
2 ParseResult, Parser, ParserExt, ParserHandle, ParserNoValue, ParserOutput, ParserRegistry,
3};
4
5pub mod shorthand {
6 use super::*;
7
8 pub fn seq(values: impl IntoIterator<Item = ParserHandle>) -> ParserHandle {
9 SequenceParser::from_iter(values).into_handle()
10 }
11
12 pub fn seq_del(
13 delimiter: ParserHandle,
14 values: impl IntoIterator<Item = ParserHandle>,
15 ) -> ParserHandle {
16 let mut result = SequenceDelimitedParser::new(delimiter);
17 for parser in values {
18 result.push(parser);
19 }
20 result.into_handle()
21 }
22
23 pub fn seq_inv(values: impl IntoIterator<Item = ParserHandle>) -> ParserHandle {
24 SequenceParser::from_iter(values)
25 .ignore_no_value(true)
26 .into_handle()
27 }
28
29 pub fn seq_del_inv(
30 delimiter: ParserHandle,
31 values: impl IntoIterator<Item = ParserHandle>,
32 ) -> ParserHandle {
33 let mut result = SequenceDelimitedParser::new(delimiter).ignore_no_value(true);
34 for parser in values {
35 result.push(parser);
36 }
37 result.into_handle()
38 }
39}
40
41#[derive(Default, Clone)]
42pub struct SequenceParser {
43 parsers: Vec<ParserHandle>,
44 ignore_no_value: bool,
45}
46
47impl SequenceParser {
48 pub fn with(mut self, parser: ParserHandle) -> Self {
49 self.push(parser);
50 self
51 }
52
53 pub fn ignore_no_value(mut self, ignore: bool) -> Self {
54 self.ignore_no_value = ignore;
55 self
56 }
57
58 pub fn push(&mut self, parser: ParserHandle) {
59 self.parsers.push(parser);
60 }
61}
62
63impl Parser for SequenceParser {
64 fn parse<'a>(&self, registry: &ParserRegistry, mut input: &'a str) -> ParseResult<'a> {
65 let mut result = Vec::with_capacity(self.parsers.len());
66 for parser in &self.parsers {
67 let (new_input, value) = parser.parse(registry, input)?;
68 input = new_input;
69 if !self.ignore_no_value || !value.is::<ParserNoValue>() {
70 result.push(value);
71 }
72 }
73 Ok((input, ParserOutput::new(result).ok().unwrap()))
74 }
75}
76
77impl FromIterator<ParserHandle> for SequenceParser {
78 fn from_iter<T: IntoIterator<Item = ParserHandle>>(iter: T) -> Self {
79 Self {
80 parsers: iter.into_iter().collect(),
81 ignore_no_value: false,
82 }
83 }
84}
85
86#[derive(Clone)]
87pub struct SequenceDelimitedParser {
88 delimiter: ParserHandle,
89 parsers: Vec<ParserHandle>,
90 ignore_no_value: bool,
91}
92
93impl SequenceDelimitedParser {
94 pub fn new(delimiter: ParserHandle) -> Self {
95 Self {
96 delimiter,
97 parsers: Default::default(),
98 ignore_no_value: false,
99 }
100 }
101
102 pub fn with(mut self, parser: ParserHandle) -> Self {
103 self.push(parser);
104 self
105 }
106
107 pub fn ignore_no_value(mut self, ignore: bool) -> Self {
108 self.ignore_no_value = ignore;
109 self
110 }
111
112 pub fn push(&mut self, parser: ParserHandle) {
113 self.parsers.push(parser);
114 }
115}
116
117impl Parser for SequenceDelimitedParser {
118 fn parse<'a>(&self, registry: &ParserRegistry, mut input: &'a str) -> ParseResult<'a> {
119 let mut result = Vec::with_capacity(self.parsers.len() * 2);
120 for (index, parser) in self.parsers.iter().enumerate() {
121 if index > 0 {
122 let (new_input, _) = self.delimiter.parse(registry, input)?;
123 input = new_input;
124 }
125 let (new_input, value) = parser.parse(registry, input)?;
126 input = new_input;
127 if !self.ignore_no_value || !value.is::<ParserNoValue>() {
128 result.push(value);
129 }
130 }
131 Ok((input, ParserOutput::new(result).ok().unwrap()))
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use crate::{
138 ParserNoValue, ParserOutput, ParserRegistry,
139 sequence::{SequenceDelimitedParser, SequenceParser},
140 shorthand::{erase, lit, seq, seq_del, seq_del_inv, seq_inv, ws},
141 };
142
143 fn is_async<T: Send + Sync>() {}
144
145 #[test]
146 fn test_sequence() {
147 is_async::<SequenceParser>();
148
149 let registry = ParserRegistry::default();
150 let sentence = seq([lit("foo"), ws(), lit("="), ws(), lit("bar")]);
151 let (rest, result) = sentence.parse(®istry, "foo = bar").unwrap();
152 assert_eq!(rest, "");
153 let result = result.consume::<Vec<ParserOutput>>().ok().unwrap();
154 assert_eq!(result.len(), 5);
155 for result in result {
156 assert!(result.read::<String>().is_some() || result.read::<ParserNoValue>().is_some());
157 }
158 assert_eq!(
159 format!("{}", sentence.parse(®istry, "foo = ").err().unwrap()),
160 "Expected 'bar'"
161 );
162
163 let sentence = seq_inv([lit("foo"), ws(), lit("="), ws(), lit("bar")]);
164 let (rest, result) = sentence.parse(®istry, "foo = bar").unwrap();
165 assert_eq!(rest, "");
166 let result = result.consume::<Vec<ParserOutput>>().ok().unwrap();
167 assert_eq!(result.len(), 3);
168 for result in result {
169 assert!(result.read::<String>().is_some());
170 }
171 assert_eq!(
172 format!("{}", sentence.parse(®istry, "foo = ").err().unwrap()),
173 "Expected 'bar'"
174 );
175 }
176
177 #[test]
178 fn test_sequence_delimited() {
179 is_async::<SequenceDelimitedParser>();
180
181 let registry = ParserRegistry::default();
182 let sentence = seq_del(ws(), [lit("foo"), lit("="), lit("bar")]);
183 let (rest, result) = sentence.parse(®istry, "foo = bar").unwrap();
184 assert_eq!(rest, "");
185 let result = result.consume::<Vec<ParserOutput>>().ok().unwrap();
186 assert_eq!(result.len(), 3);
187 for result in result {
188 assert!(result.read::<String>().is_some() || result.read::<()>().is_some());
189 }
190 assert_eq!(
191 format!("{}", sentence.parse(®istry, "foo = ").err().unwrap()),
192 "Expected 'bar'"
193 );
194
195 let sentence = seq_del_inv(ws(), [erase(lit("foo")), lit("="), lit("bar")]);
196 let (rest, result) = sentence.parse(®istry, "foo = bar").unwrap();
197 assert_eq!(rest, "");
198 let result = result.consume::<Vec<ParserOutput>>().ok().unwrap();
199 assert_eq!(result.len(), 2);
200 for result in result {
201 assert!(result.read::<String>().is_some());
202 }
203 assert_eq!(
204 format!("{}", sentence.parse(®istry, "foo = ").err().unwrap()),
205 "Expected 'bar'"
206 );
207 }
208}