intuicio_parser/
sequence.rs1use crate::{ParseResult, Parser, ParserExt, ParserHandle, ParserOutput, ParserRegistry};
2
3pub mod shorthand {
4 use super::*;
5
6 pub fn seq(values: impl IntoIterator<Item = ParserHandle>) -> ParserHandle {
7 SequenceParser::from_iter(values).into_handle()
8 }
9
10 pub fn seq_del(
11 delimiter: ParserHandle,
12 values: impl IntoIterator<Item = ParserHandle>,
13 ) -> ParserHandle {
14 let mut result = SequenceDelimitedParser::new(delimiter);
15 for parser in values {
16 result.push(parser);
17 }
18 result.into_handle()
19 }
20}
21
22#[derive(Default, Clone)]
23pub struct SequenceParser {
24 parsers: Vec<ParserHandle>,
25}
26
27impl SequenceParser {
28 pub fn with(mut self, parser: ParserHandle) -> Self {
29 self.push(parser);
30 self
31 }
32
33 pub fn push(&mut self, parser: ParserHandle) {
34 self.parsers.push(parser);
35 }
36}
37
38impl Parser for SequenceParser {
39 fn parse<'a>(&self, registry: &ParserRegistry, mut input: &'a str) -> ParseResult<'a> {
40 let mut result = Vec::with_capacity(self.parsers.len());
41 for parser in &self.parsers {
42 let (new_input, value) = parser.parse(registry, input)?;
43 input = new_input;
44 result.push(value);
45 }
46 Ok((input, ParserOutput::new(result).ok().unwrap()))
47 }
48}
49
50impl FromIterator<ParserHandle> for SequenceParser {
51 fn from_iter<T: IntoIterator<Item = ParserHandle>>(iter: T) -> Self {
52 Self {
53 parsers: iter.into_iter().collect(),
54 }
55 }
56}
57
58#[derive(Clone)]
59pub struct SequenceDelimitedParser {
60 delimiter: ParserHandle,
61 parsers: Vec<ParserHandle>,
62}
63
64impl SequenceDelimitedParser {
65 pub fn new(delimiter: ParserHandle) -> Self {
66 Self {
67 delimiter,
68 parsers: Default::default(),
69 }
70 }
71
72 pub fn with(mut self, parser: ParserHandle) -> Self {
73 self.push(parser);
74 self
75 }
76
77 pub fn push(&mut self, parser: ParserHandle) {
78 self.parsers.push(parser);
79 }
80}
81
82impl Parser for SequenceDelimitedParser {
83 fn parse<'a>(&self, registry: &ParserRegistry, mut input: &'a str) -> ParseResult<'a> {
84 let mut result = Vec::with_capacity(self.parsers.len() * 2);
85 for (index, parser) in self.parsers.iter().enumerate() {
86 if index > 0 {
87 let (new_input, _) = self.delimiter.parse(registry, input)?;
88 input = new_input;
89 }
90 let (new_input, value) = parser.parse(registry, input)?;
91 input = new_input;
92 result.push(value);
93 }
94 Ok((input, ParserOutput::new(result).ok().unwrap()))
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use crate::{
101 sequence::{SequenceDelimitedParser, SequenceParser},
102 shorthand::{lit, seq, seq_del, ws},
103 ParserNoValue, ParserOutput, ParserRegistry,
104 };
105
106 fn is_async<T: Send + Sync>() {}
107
108 #[test]
109 fn test_sequence() {
110 is_async::<SequenceParser>();
111
112 let registry = ParserRegistry::default();
113 let sentence = seq([lit("foo"), ws(), lit("="), ws(), lit("bar")]);
114 let (rest, result) = sentence.parse(®istry, "foo = bar").unwrap();
115 assert_eq!(rest, "");
116 let result = result.consume::<Vec<ParserOutput>>().ok().unwrap();
117 assert_eq!(result.len(), 5);
118 for result in result {
119 assert!(result.read::<String>().is_some() || result.read::<ParserNoValue>().is_some());
120 }
121 assert_eq!(
122 format!("{}", sentence.parse(®istry, "foo = ").err().unwrap()),
123 "Expected 'bar'"
124 );
125 }
126
127 #[test]
128 fn test_sequence_delimited() {
129 is_async::<SequenceDelimitedParser>();
130
131 let registry = ParserRegistry::default();
132 let sentence = seq_del(ws(), [lit("foo"), lit("="), lit("bar")]);
133 let (rest, result) = sentence.parse(®istry, "foo = bar").unwrap();
134 assert_eq!(rest, "");
135 let result = result.consume::<Vec<ParserOutput>>().ok().unwrap();
136 assert_eq!(result.len(), 3);
137 for result in result {
138 assert!(result.read::<String>().is_some() || result.read::<()>().is_some());
139 }
140 assert_eq!(
141 format!("{}", sentence.parse(®istry, "foo = ").err().unwrap()),
142 "Expected 'bar'"
143 );
144 }
145}