1use std::sync::Arc;
2
3use crate::{CreateParserState, ParseResult, ParseStatus, Parser};
4
5#[derive(Debug, PartialEq, Eq, Copy, Clone)]
7pub enum SequenceParserState<P1, P2, O1> {
8 FirstParser(P1),
10 SecondParser(P2, O1),
12}
13
14impl<P1, P2, O1> SequenceParserState<P1, P2, O1> {
15 pub fn new(state1: P1) -> Self {
17 Self::FirstParser(state1)
18 }
19}
20
21impl<P1: Default, P2, O1> Default for SequenceParserState<P1, P2, O1> {
22 fn default() -> Self {
23 SequenceParserState::FirstParser(Default::default())
24 }
25}
26
27impl<P1: CreateParserState, P2: CreateParserState> CreateParserState for SequenceParser<P1, P2> {
28 fn create_parser_state(&self) -> <Self as Parser>::PartialState {
29 SequenceParserState::FirstParser(self.parser1.create_parser_state())
30 }
31}
32
33#[derive(Default, Debug, PartialEq, Eq, Copy, Clone)]
35pub struct SequenceParser<P1, P2> {
36 parser1: P1,
37 parser2: P2,
38}
39
40impl<P1, P2> SequenceParser<P1, P2> {
41 pub fn new(parser1: P1, parser2: P2) -> Self {
43 Self { parser1, parser2 }
44 }
45}
46
47impl<P1: Parser, P2: CreateParserState> Parser for SequenceParser<P1, P2> {
48 type Output = (P1::Output, P2::Output);
49 type PartialState = SequenceParserState<P1::PartialState, P2::PartialState, P1::Output>;
50
51 fn parse<'a>(
52 &self,
53 state: &Self::PartialState,
54 input: &'a [u8],
55 ) -> crate::ParseResult<ParseStatus<'a, Self::PartialState, Self::Output>> {
56 match state {
57 SequenceParserState::FirstParser(p1) => {
58 let result = self.parser1.parse(p1, input)?;
59 match result {
60 ParseStatus::Finished {
61 result: o1,
62 remaining,
63 } => {
64 let second_parser_state = self.parser2.create_parser_state();
65 let result = self.parser2.parse(&second_parser_state, remaining)?;
66 match result {
67 ParseStatus::Finished { result, remaining } => {
68 Ok(ParseStatus::Finished {
69 result: (o1, result),
70 remaining,
71 })
72 }
73 ParseStatus::Incomplete {
74 new_state: p2,
75 required_next,
76 } => {
77 let new_state = SequenceParserState::SecondParser(p2, o1);
78 Ok(ParseStatus::Incomplete {
79 new_state,
80 required_next,
81 })
82 }
83 }
84 }
85 ParseStatus::Incomplete {
86 new_state: p1,
87 required_next,
88 } => {
89 let new_state = SequenceParserState::FirstParser(p1);
90 Ok(ParseStatus::Incomplete {
91 new_state,
92 required_next,
93 })
94 }
95 }
96 }
97 SequenceParserState::SecondParser(p2, o1) => {
98 let result = self.parser2.parse(p2, input)?;
99 match result {
100 ParseStatus::Finished { result, remaining } => Ok(ParseStatus::Finished {
101 result: (o1.clone(), result),
102 remaining,
103 }),
104 ParseStatus::Incomplete {
105 new_state: p2,
106 required_next,
107 } => {
108 let new_state = SequenceParserState::SecondParser(p2, o1.clone());
109 Ok(ParseStatus::Incomplete {
110 new_state,
111 required_next,
112 })
113 }
114 }
115 }
116 }
117 }
118}
119
120#[test]
121fn sequence_parser() {
122 use crate::{LiteralParser, LiteralParserOffset};
123 let parser = SequenceParser {
124 parser1: LiteralParser::new("Hello, "),
125 parser2: LiteralParser::new("world!"),
126 };
127 let state = SequenceParserState::FirstParser(LiteralParserOffset::default());
128 assert_eq!(
129 parser.parse(&state, b"Hello, world!"),
130 Ok(ParseStatus::Finished {
131 result: ((), ()),
132 remaining: &[]
133 })
134 );
135 assert_eq!(
136 parser.parse(&state, b"Hello, "),
137 Ok(ParseStatus::Incomplete {
138 new_state: SequenceParserState::SecondParser(LiteralParserOffset::new(0), ()),
139 required_next: "world!".into()
140 })
141 );
142 assert_eq!(
143 parser.parse(
144 &parser
145 .parse(&state, b"Hello, ")
146 .unwrap()
147 .unwrap_incomplete()
148 .0,
149 b"world!"
150 ),
151 Ok(ParseStatus::Finished {
152 result: ((), ()),
153 remaining: &[]
154 })
155 );
156 assert!(parser.parse(&state, b"Goodbye, world!").is_err(),);
157}
158
159#[derive(Debug, PartialEq, Eq)]
161pub enum ThenLazyParserState<P1: Parser, P2: Parser> {
162 FirstParser(P1::PartialState),
164 SecondParser {
166 first_output: P1::Output,
168 second_parser: Arc<P2>,
170 second_state: P2::PartialState,
172 },
173}
174
175impl<P1: Parser, P2: Parser> Clone for ThenLazyParserState<P1, P2>
176where
177 P1::PartialState: Clone,
178 P2::PartialState: Clone,
179{
180 fn clone(&self) -> Self {
181 match self {
182 Self::FirstParser(first_state) => Self::FirstParser(first_state.clone()),
183 Self::SecondParser {
184 first_output,
185 second_parser,
186 second_state,
187 } => Self::SecondParser {
188 first_output: first_output.clone(),
189 second_parser: second_parser.clone(),
190 second_state: second_state.clone(),
191 },
192 }
193 }
194}
195
196impl<P1: Parser, P2: Parser> ThenLazyParserState<P1, P2> {
197 pub fn new(first_state: P1::PartialState) -> Self {
199 Self::FirstParser(first_state)
200 }
201}
202
203impl<P1: Parser, P2: Parser> Default for ThenLazyParserState<P1, P2>
204where
205 P1::PartialState: Default,
206{
207 fn default() -> Self {
208 Self::FirstParser(Default::default())
209 }
210}
211
212pub struct ThenLazy<P1, F> {
214 parser1: P1,
215 parser_fn: F,
216}
217
218impl<P1: Parser, P2: CreateParserState, F: Fn(&P1::Output) -> P2> ThenLazy<P1, F> {
219 pub fn new(parser1: P1, parser_fn: F) -> Self {
221 Self { parser1, parser_fn }
222 }
223}
224
225impl<P1: CreateParserState, P2: CreateParserState, F: Fn(&P1::Output) -> P2> CreateParserState
226 for ThenLazy<P1, F>
227{
228 fn create_parser_state(&self) -> <Self as Parser>::PartialState {
229 ThenLazyParserState::FirstParser(self.parser1.create_parser_state())
230 }
231}
232
233impl<P1: Parser, P2: CreateParserState, F: Fn(&P1::Output) -> P2> Parser for ThenLazy<P1, F> {
234 type Output = (P1::Output, P2::Output);
235 type PartialState = ThenLazyParserState<P1, P2>;
236
237 fn parse<'a>(
238 &self,
239 state: &Self::PartialState,
240 input: &'a [u8],
241 ) -> ParseResult<ParseStatus<'a, Self::PartialState, Self::Output>> {
242 match state {
243 ThenLazyParserState::FirstParser(p1) => {
244 let result = self.parser1.parse(p1, input)?;
245 match result {
246 ParseStatus::Finished {
247 result: o1,
248 remaining,
249 } => {
250 let parser2 = Arc::new((self.parser_fn)(&o1));
251 let second_parser_state = parser2.create_parser_state();
252 let result = parser2.parse(&second_parser_state, remaining)?;
253 match result {
254 ParseStatus::Finished { result, remaining } => {
255 Ok(ParseStatus::Finished {
256 result: (o1, result),
257 remaining,
258 })
259 }
260 ParseStatus::Incomplete {
261 new_state: p2,
262 required_next,
263 } => {
264 let new_state = ThenLazyParserState::SecondParser {
265 first_output: o1.clone(),
266 second_parser: parser2.clone(),
267 second_state: p2,
268 };
269 Ok(ParseStatus::Incomplete {
270 new_state,
271 required_next,
272 })
273 }
274 }
275 }
276 ParseStatus::Incomplete {
277 new_state: p1,
278 required_next,
279 } => {
280 let new_state = ThenLazyParserState::FirstParser(p1);
281 Ok(ParseStatus::Incomplete {
282 new_state,
283 required_next,
284 })
285 }
286 }
287 }
288 ThenLazyParserState::SecondParser {
289 first_output,
290 second_parser,
291 second_state,
292 } => {
293 let result = second_parser.parse(second_state, input)?;
294 match result {
295 ParseStatus::Finished { result, remaining } => Ok(ParseStatus::Finished {
296 result: (first_output.clone(), result),
297 remaining,
298 }),
299 ParseStatus::Incomplete {
300 new_state: p2,
301 required_next,
302 } => {
303 let new_state = ThenLazyParserState::SecondParser {
304 first_output: first_output.clone(),
305 second_parser: second_parser.clone(),
306 second_state: p2,
307 };
308 Ok(ParseStatus::Incomplete {
309 new_state,
310 required_next,
311 })
312 }
313 }
314 }
315 }
316 }
317}