1 //! Combinators which take multiple parsers and applies them one after another.
2
3 use crate::{
4 error::{
5 ParseError,
6 ParseResult::{self, *},
7 StreamError, Tracked,
8 },
9 lib::marker::PhantomData,
10 parser::{
11 combinator::{ignore, Ignore, Map},
12 ParseMode,
13 },
14 ErrorOffset, Parser, Stream, StreamOnce,
15 };
16
17 macro_rules! dispatch_on {
18 ($i: expr, $f: expr;) => {
19 };
20 ($i: expr, $f: expr; $first: ident $(, $id: ident)*) => { {
21 let b = $f($i, $first);
22 if b {
23 dispatch_on!($i + 1, $f; $($id),*);
24 }
25 } }
26 }
27
28 macro_rules! count {
29 () => { 0 };
30 ($f: ident) => { 1 };
31 ($f: ident, $($rest: ident),+) => { 1 + count!($($rest),*) };
32 }
33
34 #[doc(hidden)]
35 pub struct SequenceState<T, U> {
36 pub value: Option<T>,
37 pub state: U,
38 }
39
40 impl<T, U: Default> Default for SequenceState<T, U> {
default() -> Self41 fn default() -> Self {
42 SequenceState {
43 value: None,
44 state: U::default(),
45 }
46 }
47 }
48
49 impl<T, U> SequenceState<T, U>
50 where
51 U: Default,
52 {
unwrap_value(&mut self) -> T53 unsafe fn unwrap_value(&mut self) -> T {
54 match self.value.take() {
55 Some(t) => t,
56 None => core::hint::unreachable_unchecked(),
57 }
58 }
59 }
60
61 macro_rules! last_ident {
62 ($id: ident) => { $id };
63 ($id: ident, $($rest: ident),+) => { last_ident!($($rest),+) };
64 }
65
66 macro_rules! tuple_parser {
67 ($partial_state: ident; $h: ident $(, $id: ident)*) => {
68 #[allow(non_snake_case)]
69 #[derive(Default)]
70 pub struct $partial_state < $h $(, $id )* > {
71 pub $h: $h,
72 $(
73 pub $id: $id,
74 )*
75 #[allow(dead_code)]
76 offset: u8,
77 _marker: PhantomData <( $h, $( $id),* )>,
78 }
79
80
81 #[allow(non_snake_case)]
82 impl<$h $(, $id)*> $partial_state<$h $(, $id)*> {
83 #[allow(dead_code)]
84 fn add_errors<Input>(
85 input: &mut Input,
86 mut err: Tracked<Input::Error>,
87 first_empty_parser: usize,
88 offset: u8,
89 $h: &mut $h $(, $id : &mut $id )*
90 ) -> ParseResult<($h::Output, $($id::Output),*), <Input as StreamOnce>::Error>
91 where Input: Stream,
92 Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
93 $h: Parser<Input>,
94 $($id: Parser<Input>),*
95 {
96 let inner_offset = err.offset;
97 err.offset = ErrorOffset(offset);
98 if first_empty_parser != 0 {
99 if let Ok(t) = input.uncons() {
100 err.error.add(StreamError::unexpected_token(t));
101 }
102 dispatch_on!(0, |i, mut p| {
103 if i + 1 == first_empty_parser {
104 Parser::add_committed_expected_error(&mut p, &mut err);
105 }
106 if i >= first_empty_parser {
107 if err.offset <= ErrorOffset(1) {
108 // We reached the last parser we need to add errors to (and the
109 // parser that actually returned the error), use the returned
110 // offset for that parser.
111 err.offset = inner_offset;
112 }
113 Parser::add_error(&mut p, &mut err);
114 if err.offset <= ErrorOffset(1) {
115 return false;
116 }
117 }
118 err.offset = ErrorOffset(
119 err.offset.0.saturating_sub(Parser::parser_count(&p).0)
120 );
121 true
122 }; $h $(, $id)*);
123 CommitErr(err.error)
124 } else {
125 PeekErr(err)
126 }
127 }
128 }
129
130 #[allow(non_snake_case)]
131 impl <Input: Stream, $h:, $($id:),*> Parser<Input> for ($h, $($id),*)
132 where Input: Stream,
133 Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
134 $h: Parser<Input>,
135 $($id: Parser<Input>),*
136 {
137
138 type Output = ($h::Output, $($id::Output),*);
139 type PartialState = $partial_state<
140 SequenceState<$h::Output, $h::PartialState>
141 $(, SequenceState<$id::Output, $id::PartialState>)*
142 >;
143
144 parse_mode!(Input);
145 #[inline]
146 fn parse_mode_impl<MODE>(
147 &mut self,
148 mut mode: MODE,
149 input: &mut Input,
150 state: &mut Self::PartialState,
151 ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
152 where
153 MODE: ParseMode,
154 {
155 let (ref mut $h, $(ref mut $id),*) = *self;
156 let mut first_empty_parser = 0;
157 #[allow(unused_mut)]
158 let mut current_parser = 0;
159
160 #[allow(unused_macros)]
161 macro_rules! add_errors {
162 ($err: ident, $offset: expr) => {
163 $partial_state::add_errors(
164 input, $err, first_empty_parser, $offset, $h, $($id),*
165 )
166 }
167 }
168
169 if mode.is_first() || state.$h.value.is_none() {
170 let temp = match $h.parse_mode(mode, input, &mut state.$h.state) {
171 CommitOk(x) => {
172 first_empty_parser = current_parser + 1;
173 x
174 }
175 PeekErr(err) => return PeekErr(err),
176 CommitErr(err) => return CommitErr(err),
177 PeekOk(x) => {
178 x
179 }
180 };
181 state.offset = $h.parser_count().0.saturating_add(1);
182 // SAFETY: must be set to avoid UB below when unwrapping
183 state.$h.value = Some(temp);
184
185 // Once we have successfully parsed the partial input we may resume parsing in
186 // "first mode"
187 mode.set_first();
188 }
189
190 $(
191 if mode.is_first() || state.$id.value.is_none() {
192 current_parser += 1;
193 let before = input.checkpoint();
194 let temp = match $id.parse_mode(mode, input, &mut state.$id.state) {
195 CommitOk(x) => {
196 first_empty_parser = current_parser + 1;
197 x
198 }
199 PeekErr(err) => {
200 if let Err(err) = input.reset(before) {
201 return if first_empty_parser != 0 {
202 CommitErr(err.into())
203 } else {
204 PeekErr(err.into())
205 };
206 }
207 return add_errors!(err, state.offset)
208 }
209 CommitErr(err) => return CommitErr(err),
210 PeekOk(x) => {
211 x
212 }
213 };
214 state.offset = state.offset.saturating_add($id.parser_count().0);
215 // SAFETY: must be set to avoid UB below when unwrapping
216 state.$id.value = Some(temp);
217
218 // Once we have successfully parsed the partial input we may resume parsing in
219 // "first mode"
220 mode.set_first();
221 }
222 )*
223
224 // SAFETY: requires both $h and $id to be set, see previous SAFETY comments
225 let value = unsafe { (state.$h.unwrap_value(), $(state.$id.unwrap_value()),*) };
226 if first_empty_parser != 0 {
227 CommitOk(value)
228 } else {
229 PeekOk(value)
230 }
231 }
232
233 #[inline]
234 fn parser_count(&self) -> ErrorOffset {
235 let (ref $h, $(ref $id),*) = *self;
236 ErrorOffset($h.parser_count().0 $( + $id.parser_count().0)*)
237 }
238
239 #[inline]
240 fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
241 let (ref mut $h, $(ref mut $id),*) = *self;
242 let prev = errors.offset;
243 $h.add_error(errors);
244 if errors.offset <= ErrorOffset(1) {
245 errors.offset = ErrorOffset(
246 errors.offset.0.saturating_sub(1)
247 );
248 return;
249 }
250 if errors.offset == prev {
251 errors.offset = ErrorOffset(errors.offset.0.saturating_sub($h.parser_count().0));
252 }
253
254 #[allow(dead_code)]
255 const LAST: usize = count!($($id),*);
256 #[allow(unused_mut, unused_variables)]
257 let mut i = 0;
258 $(
259 i += 1;
260 let prev = errors.offset;
261 $id.add_error(errors);
262 if errors.offset <= ErrorOffset(1) {
263 errors.offset = ErrorOffset(
264 errors.offset.0.saturating_sub(1)
265 );
266 return;
267 }
268 if i != LAST && errors.offset == prev {
269 errors.offset = ErrorOffset(
270 errors.offset.0.saturating_sub($id.parser_count().0)
271 );
272 }
273 )*
274 }
275
276 fn add_committed_expected_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
277 #[allow(unused_variables)]
278 let (ref mut $h, $(ref mut $id),*) = *self;
279 last_ident!($h $(, $id)*).add_committed_expected_error(errors)
280 }
281 }
282 }
283 }
284
285 tuple_parser!(PartialState1; A);
286 tuple_parser!(PartialState2; A, B);
287 tuple_parser!(PartialState3; A, B, C);
288 tuple_parser!(PartialState4; A, B, C, D);
289 tuple_parser!(PartialState5; A, B, C, D, E);
290 tuple_parser!(PartialState6; A, B, C, D, E, F);
291 tuple_parser!(PartialState7; A, B, C, D, E, F, G);
292 tuple_parser!(PartialState8; A, B, C, D, E, F, G, H);
293 tuple_parser!(PartialState9; A, B, C, D, E, F, G, H, I);
294 tuple_parser!(PartialState10; A, B, C, D, E, F, G, H, I, J);
295 tuple_parser!(PartialState11; A, B, C, D, E, F, G, H, I, J, K);
296 tuple_parser!(PartialState12; A, B, C, D, E, F, G, H, I, J, K, L);
297 tuple_parser!(PartialState13; A, B, C, D, E, F, G, H, I, J, K, L, M);
298 tuple_parser!(PartialState14; A, B, C, D, E, F, G, H, I, J, K, L, M, N);
299 tuple_parser!(PartialState15; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P);
300 tuple_parser!(PartialState16; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q);
301 tuple_parser!(PartialState17; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R);
302 tuple_parser!(PartialState18; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R, S);
303 tuple_parser!(PartialState19; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R, S, T);
304 tuple_parser!(PartialState20; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R, S, T, U);
305
306 #[macro_export]
307 #[doc(hidden)]
308 macro_rules! seq_parser_expr {
309 (; $($tt: tt)*) => {
310 ( $($tt)* )
311 };
312 ( (_ : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
313 $crate::seq_parser_expr!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
314 };
315 ( ($first_field: ident : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
316 $crate::seq_parser_expr!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
317 };
318 ( (_ : $first_parser: expr ); $($tt: tt)*) => {
319 ( $($tt)* $first_parser, )
320 };
321 ( ($first_field: ident : $first_parser: expr, ); $($tt: tt)*) => {
322 $crate::seq_parser_expr!(; $($tt)* $first_parser,)
323 };
324 ( (_ : $first_parser: expr, ); $($tt: tt)*) => {
325 ( $($tt)* $first_parser, )
326 };
327 ( ($first_field: ident : $first_parser: expr ); $($tt: tt)*) => {
328 $crate::seq_parser_expr!(; $($tt)* $first_parser,)
329 };
330 }
331
332 #[macro_export]
333 #[doc(hidden)]
334 macro_rules! seq_parser_pattern {
335 (; $($tt: tt)*) => {
336 ( $($tt)* )
337 };
338 ( (_ : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
339 $crate::seq_parser_pattern!( ( $($remaining)+ ) ; $($tt)* _, )
340 };
341 ( ($first_field: ident : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
342 $crate::seq_parser_pattern!( ( $($remaining)+ ) ; $($tt)* $first_field, )
343 };
344 ( ( _ : $first_parser: expr ); $($tt: tt)*) => {
345 $crate::seq_parser_pattern!(; $($tt)* _, )
346 };
347 ( ($first_field: ident : $first_parser: expr ); $($tt: tt)*) => {
348 $crate::seq_parser_pattern!(; $($tt)* $first_field,)
349 };
350 ( ( _ : $first_parser: expr, ); $($tt: tt)*) => {
351 $crate::seq_parser_pattern!(; $($tt)* _, )
352 };
353 ( ($first_field: ident : $first_parser: expr, ); $($tt: tt)*) => {
354 $crate::seq_parser_pattern!(; $($tt)* $first_field,)
355 };
356 }
357
358 #[macro_export]
359 #[doc(hidden)]
360 macro_rules! seq_parser_impl {
361 (; $name: ident $($tt: tt)*) => {
362 $name { $($tt)* }
363 };
364 ( (_ : $first_parser: expr, $($remaining: tt)+ ); $name: ident $($tt: tt)*) => {
365 $crate::seq_parser_impl!( ( $($remaining)+ ) ; $name $($tt)* )
366 };
367 ( ($first_field: ident : $first_parser: expr, $($remaining: tt)+ );
368 $name: ident $($tt: tt)*) =>
369 {
370 $crate::seq_parser_impl!( ( $($remaining)+ ) ; $name $($tt)* $first_field: $first_field, )
371 };
372 ( ( _ : $first_parser: expr ); $name: ident $($tt: tt)*) => {
373 $crate::seq_parser_impl!( ; $name $($tt)* )
374 };
375 ( ($first_field: ident : $first_parser: expr ); $name: ident $($tt: tt)*) => {
376 $crate::seq_parser_impl!(; $name $($tt)* $first_field: $first_field,)
377 };
378 ( ( _ : $first_parser: expr, ); $name: ident $($tt: tt)*) => {
379 $crate::seq_parser_impl!(; $name $($tt)*)
380 };
381 ( ($first_field: ident : $first_parser: expr, ); $name: ident $($tt: tt)*) => {
382 $crate::seq_parser_impl!(; $name $($tt)* $first_field: $first_field,)
383 };
384 }
385
386 #[macro_export]
387 #[doc(hidden)]
388 macro_rules! seq_tuple_extract {
389 (; ; $name: ident ; $($arg: expr),* $(,)? ) => {
390 $name( $($arg,)* )
391 };
392
393 ( (_ : $first_parser: expr, $($remaining: tt)+ ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
394 $crate::seq_tuple_extract!( ( $($remaining)+ ); ( $($arg),* ) ; $($tt)* )
395 };
396
397 ( ($first_parser: expr, $($remaining: tt)+ ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
398 $crate::seq_tuple_extract!( ( $($remaining)+ ) ; ( $($arg),* ) ; $($tt)* $first_arg, )
399 };
400
401 ( (_ : $first_parser: expr $(,)? ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
402 $crate::seq_tuple_extract!(; ; $($tt)*)
403 };
404
405 ( ($first_parser: expr $(,)? ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
406 $crate::seq_tuple_extract!(; ; $($tt)* $first_arg)
407 };
408 }
409
410 #[macro_export]
411 #[doc(hidden)]
412 macro_rules! seq_tuple_parser_impl {
413 (; $($tt: tt)*) => {
414 ($($tt)*)
415 };
416
417 ( (_ : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
418 $crate::seq_tuple_parser_impl!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
419 };
420
421 ( ($first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
422 $crate::seq_tuple_parser_impl!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
423 };
424
425 ( (_ : $first_parser: expr $(,)? ); $($tt: tt)*) => {
426 $crate::seq_tuple_parser_impl!(; $($tt)* $first_parser, )
427 };
428
429 ( ($first_parser: expr $(,)? ); $($tt: tt)*) => {
430 $crate::seq_tuple_parser_impl!(; $($tt)* $first_parser, )
431 };
432 }
433
434 /// Sequences multiple parsers and builds a struct out of them.
435 ///
436 /// ```
437 /// use combine::{Parser, between, from_str, many, struct_parser, token};
438 /// use combine::parser::range::take_while1;
439 /// use combine::parser::byte::{letter, spaces};
440 ///
441 /// #[derive(Debug, PartialEq)]
442 /// struct Point(u32, u32);
443 ///
444 /// #[derive(Debug, PartialEq)]
445 /// struct Field {
446 /// name: Vec<u8>,
447 /// value: Vec<u8>,
448 /// point: Point,
449 /// }
450 /// fn main() {
451 /// let num = || from_str(take_while1(|b: u8| b >= b'0' && b <= b'9'));
452 /// let spaced = |b| between(spaces(), spaces(), token(b));
453 /// let mut parser = struct_parser!{
454 /// Field {
455 /// name: many(letter()),
456 /// // `_` fields are ignored when building the struct
457 /// _: spaced(b':'),
458 /// value: many(letter()),
459 /// _: spaced(b':'),
460 /// point: struct_parser!(Point(num(), _: spaced(b','), num())),
461 /// }
462 /// };
463 /// assert_eq!(
464 /// parser.parse(&b"test: data: 123 , 4"[..]),
465 /// Ok((
466 /// Field {
467 /// name: b"test"[..].to_owned(),
468 /// value: b"data"[..].to_owned(),
469 /// point: Point(123, 4),
470 /// },
471 /// &b""[..]
472 /// )),
473 /// );
474 /// }
475 /// ```
476 #[macro_export]
477 macro_rules! struct_parser {
478 ($name: ident { $($tt: tt)* }) => {
479 $crate::seq_parser_expr!( ( $($tt)* ); )
480 .map(|$crate::seq_parser_pattern!( ( $($tt)* ); )|
481 $crate::seq_parser_impl!(( $($tt)* ); $name )
482 )
483 };
484
485 ($name: ident ( $($arg: tt)* )) => {
486 $crate::seq_tuple_parser_impl!( ( $($arg)* ) ; )
487 .map(|t|
488 $crate::seq_tuple_extract!(
489 ( $($arg)* );
490 (t.0, t.1, t.2, t.3, t.4, t.5, t.6, t.7, t.8, t.9, t.10, t.11, t.12, t.13, t.14);
491 $name ;
492 )
493 )
494 }
495 }
496
497 #[derive(Copy, Clone)]
498 pub struct With<P1, P2>((Ignore<P1>, P2));
499 impl<Input, P1, P2> Parser<Input> for With<P1, P2>
500 where
501 Input: Stream,
502 P1: Parser<Input>,
503 P2: Parser<Input>,
504 {
505 type Output = P2::Output;
506 type PartialState = <(Ignore<P1>, P2) as Parser<Input>>::PartialState;
507
508 #[inline]
parse_lazy( &mut self, input: &mut Input, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>509 fn parse_lazy(
510 &mut self,
511 input: &mut Input,
512 ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
513 self.0.parse_lazy(input).map(|(_, b)| b)
514 }
515
516 parse_mode!(Input);
517 #[inline]
parse_mode_impl<M>( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> where M: ParseMode,518 fn parse_mode_impl<M>(
519 &mut self,
520 mode: M,
521 input: &mut Input,
522 state: &mut Self::PartialState,
523 ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
524 where
525 M: ParseMode,
526 {
527 self.0.parse_mode(mode, input, state).map(|(_, b)| b)
528 }
529
530 forward_parser!(Input, add_error add_committed_expected_error parser_count, 0);
531 }
532
533 /// Equivalent to [`p1.with(p2)`].
534 ///
535 /// [`p1.with(p2)`]: ../trait.Parser.html#method.with
with<Input, P1, P2>(p1: P1, p2: P2) -> With<P1, P2> where Input: Stream, P1: Parser<Input>, P2: Parser<Input>,536 pub fn with<Input, P1, P2>(p1: P1, p2: P2) -> With<P1, P2>
537 where
538 Input: Stream,
539 P1: Parser<Input>,
540 P2: Parser<Input>,
541 {
542 With((ignore(p1), p2))
543 }
544
545 #[derive(Copy, Clone)]
546 pub struct Skip<P1, P2>((P1, Ignore<P2>));
547 impl<Input, P1, P2> Parser<Input> for Skip<P1, P2>
548 where
549 Input: Stream,
550 P1: Parser<Input>,
551 P2: Parser<Input>,
552 {
553 type Output = P1::Output;
554 type PartialState = <(P1, Ignore<P2>) as Parser<Input>>::PartialState;
555
556 parse_mode!(Input);
557 #[inline]
parse_mode_impl<M>( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> where M: ParseMode,558 fn parse_mode_impl<M>(
559 &mut self,
560 mode: M,
561 input: &mut Input,
562 state: &mut Self::PartialState,
563 ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
564 where
565 M: ParseMode,
566 {
567 self.0.parse_mode(mode, input, state).map(|(a, _)| a)
568 }
569
570 forward_parser!(Input, add_error add_committed_expected_error parser_count, 0);
571 }
572
skip<Input, P1, P2>(p1: P1, p2: P2) -> Skip<P1, P2> where Input: Stream, P1: Parser<Input>, P2: Parser<Input>,573 pub fn skip<Input, P1, P2>(p1: P1, p2: P2) -> Skip<P1, P2>
574 where
575 Input: Stream,
576 P1: Parser<Input>,
577 P2: Parser<Input>,
578 {
579 Skip((p1, ignore(p2)))
580 }
581
582 parser! {
583 #[derive(Copy, Clone)]
584 pub struct Between;
585 type PartialState = <Map<(L, P, R), fn ((L::Output, P::Output, R::Output)) -> P::Output> as Parser<Input>>::PartialState;
586 /// Parses `open` followed by `parser` followed by `close`.
587 /// Returns the value of `parser`.
588 ///
589 /// ```
590 /// # extern crate combine;
591 /// # use combine::*;
592 /// # use combine::parser::char::string;
593 /// # fn main() {
594 /// let result = between(token('['), token(']'), string("rust"))
595 /// .parse("[rust]")
596 /// .map(|x| x.0);
597 /// assert_eq!(result, Ok("rust"));
598 /// # }
599 /// ```
600 pub fn between[Input, L, R, P](open: L, close: R, parser: P)(Input) -> P::Output
601 where [
602 Input: Stream,
603 L: Parser< Input>,
604 R: Parser< Input>,
605 P: Parser< Input>,
606 ]
607 {
608 fn middle<T, U, V>((_, x, _): (T, U, V)) -> U {
609 x
610 }
611 (open, parser, close).map(middle)
612 }
613 }
614
615 #[derive(Copy, Clone)]
616 pub struct Then<P, F>(P, F);
617 impl<Input, P, N, F> Parser<Input> for Then<P, F>
618 where
619 Input: Stream,
620 F: FnMut(P::Output) -> N,
621 P: Parser<Input>,
622 N: Parser<Input>,
623 {
624 type Output = N::Output;
625 type PartialState = (P::PartialState, Option<(bool, N)>, N::PartialState);
626
627 parse_mode!(Input);
628 #[inline]
parse_mode_impl<M>( &mut self, mut mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> where M: ParseMode,629 fn parse_mode_impl<M>(
630 &mut self,
631 mut mode: M,
632 input: &mut Input,
633 state: &mut Self::PartialState,
634 ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
635 where
636 M: ParseMode,
637 {
638 let (ref mut p_state, ref mut n_parser_cache, ref mut n_state) = *state;
639
640 if mode.is_first() || n_parser_cache.is_none() {
641 debug_assert!(n_parser_cache.is_none());
642
643 let (value, committed) = match self.0.parse_mode(mode, input, p_state) {
644 PeekOk(value) => (value, false),
645 CommitOk(value) => (value, true),
646
647 PeekErr(err) => return PeekErr(err),
648 CommitErr(err) => return CommitErr(err),
649 };
650
651 *n_parser_cache = Some((committed, (self.1)(value)));
652 mode.set_first();
653 }
654
655 let result = n_parser_cache
656 .as_mut()
657 .unwrap()
658 .1
659 .parse_committed_mode(mode, input, n_state);
660 match result {
661 PeekOk(x) => {
662 let (committed, _) = *n_parser_cache.as_ref().unwrap();
663 *n_parser_cache = None;
664 if committed {
665 CommitOk(x)
666 } else {
667 PeekOk(x)
668 }
669 }
670 CommitOk(x) => {
671 *n_parser_cache = None;
672 CommitOk(x)
673 }
674 PeekErr(x) => {
675 let (committed, _) = *n_parser_cache.as_ref().unwrap();
676 *n_parser_cache = None;
677 if committed {
678 CommitErr(x.error)
679 } else {
680 PeekErr(x)
681 }
682 }
683 CommitErr(x) => CommitErr(x),
684 }
685 }
686
add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>)687 fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
688 self.0.add_error(errors);
689 }
690 }
691
692 /// Equivalent to [`p.then(f)`].
693 ///
694 /// [`p.then(f)`]: ../trait.Parser.html#method.then
then<Input, P, F, N>(p: P, f: F) -> Then<P, F> where Input: Stream, F: FnMut(P::Output) -> N, P: Parser<Input>, N: Parser<Input>,695 pub fn then<Input, P, F, N>(p: P, f: F) -> Then<P, F>
696 where
697 Input: Stream,
698 F: FnMut(P::Output) -> N,
699 P: Parser<Input>,
700 N: Parser<Input>,
701 {
702 Then(p, f)
703 }
704
705 #[derive(Copy, Clone)]
706 pub struct ThenPartial<P, F>(P, F);
707 impl<Input, P, N, F> Parser<Input> for ThenPartial<P, F>
708 where
709 Input: Stream,
710 F: FnMut(&mut P::Output) -> N,
711 P: Parser<Input>,
712 N: Parser<Input>,
713 {
714 type Output = N::Output;
715 type PartialState = (P::PartialState, Option<(bool, P::Output)>, N::PartialState);
716
717 parse_mode!(Input);
718 #[inline]
parse_mode_impl<M>( &mut self, mut mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> where M: ParseMode,719 fn parse_mode_impl<M>(
720 &mut self,
721 mut mode: M,
722 input: &mut Input,
723 state: &mut Self::PartialState,
724 ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
725 where
726 M: ParseMode,
727 {
728 let (ref mut p_state, ref mut n_parser_cache, ref mut n_state) = *state;
729
730 if mode.is_first() || n_parser_cache.is_none() {
731 debug_assert!(n_parser_cache.is_none());
732
733 match self.0.parse_mode(mode, input, p_state) {
734 PeekOk(value) => {
735 *n_parser_cache = Some((false, value));
736 }
737 CommitOk(value) => {
738 *n_parser_cache = Some((true, value));
739 }
740 PeekErr(err) => return PeekErr(err),
741 CommitErr(err) => return CommitErr(err),
742 }
743 mode.set_first();
744 }
745
746 let result = (self.1)(&mut n_parser_cache.as_mut().unwrap().1)
747 .parse_committed_mode(mode, input, n_state);
748 match result {
749 PeekOk(x) => {
750 let (committed, _) = n_parser_cache.take().unwrap();
751 if committed {
752 CommitOk(x)
753 } else {
754 PeekOk(x)
755 }
756 }
757 CommitOk(x) => {
758 *n_parser_cache = None;
759 CommitOk(x)
760 }
761 PeekErr(x) => {
762 let (committed, _) = n_parser_cache.take().unwrap();
763 if committed {
764 CommitErr(x.error)
765 } else {
766 PeekErr(x)
767 }
768 }
769 CommitErr(x) => CommitErr(x),
770 }
771 }
772
add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>)773 fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
774 self.0.add_error(errors);
775 }
776 }
777
778 /// Equivalent to [`p.then_partial(f)`].
779 ///
780 /// [`p.then_partial(f)`]: ../trait.Parser.html#method.then_partial
then_partial<Input, P, F, N>(p: P, f: F) -> ThenPartial<P, F> where Input: Stream, F: FnMut(&mut P::Output) -> N, P: Parser<Input>, N: Parser<Input>,781 pub fn then_partial<Input, P, F, N>(p: P, f: F) -> ThenPartial<P, F>
782 where
783 Input: Stream,
784 F: FnMut(&mut P::Output) -> N,
785 P: Parser<Input>,
786 N: Parser<Input>,
787 {
788 ThenPartial(p, f)
789 }
790
791 #[cfg(all(feature = "std", test))]
792 mod tests {
793
794 use crate::parser::{token::any, EasyParser};
795
796 #[test]
sequence_single_parser()797 fn sequence_single_parser() {
798 assert!((any(),).easy_parse("a").is_ok());
799 }
800 }
801
802 #[derive(Copy, Clone)]
803 pub struct ThenRef<P, F>(P, F);
804 impl<Input, P, N, F> Parser<Input> for ThenRef<P, F>
805 where
806 Input: Stream,
807 F: FnMut(&P::Output) -> N,
808 P: Parser<Input>,
809 N: Parser<Input>,
810 {
811 type Output = (P::Output, N::Output);
812 type PartialState = (
813 P::PartialState,
814 Option<(bool, P::Output, N)>,
815 N::PartialState,
816 );
817
818 parse_mode!(Input);
819 #[inline]
parse_mode_impl<M>( &mut self, mut mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> where M: ParseMode,820 fn parse_mode_impl<M>(
821 &mut self,
822 mut mode: M,
823 input: &mut Input,
824 state: &mut Self::PartialState,
825 ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
826 where
827 M: ParseMode,
828 {
829 let (ref mut p_state, ref mut n_parser_cache, ref mut n_state) = *state;
830
831 if mode.is_first() || n_parser_cache.is_none() {
832 debug_assert!(n_parser_cache.is_none());
833
834 let (value, committed) = match self.0.parse_mode(mode, input, p_state) {
835 PeekOk(value) => (value, false),
836 CommitOk(value) => (value, true),
837
838 PeekErr(err) => return PeekErr(err),
839 CommitErr(err) => return CommitErr(err),
840 };
841
842 let parser = (self.1)(&value);
843 *n_parser_cache = Some((committed, value, parser));
844
845 mode.set_first();
846 }
847
848 let result = n_parser_cache
849 .as_mut()
850 .unwrap()
851 .2
852 .parse_committed_mode(mode, input, n_state);
853 match result {
854 PeekOk(x) => {
855 let (committed, in_value, _) = n_parser_cache.take().unwrap();
856 if committed {
857 CommitOk((in_value, x))
858 } else {
859 PeekOk((in_value, x))
860 }
861 }
862 CommitOk(x) => {
863 let (_, in_value, _) = n_parser_cache.take().unwrap();
864 *n_parser_cache = None;
865 CommitOk((in_value, x))
866 }
867 PeekErr(x) => {
868 let (committed, _, _) = n_parser_cache.take().unwrap();
869 *n_parser_cache = None;
870 if committed {
871 CommitErr(x.error)
872 } else {
873 PeekErr(x)
874 }
875 }
876 CommitErr(x) => CommitErr(x),
877 }
878 }
879
add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>)880 fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
881 self.0.add_error(errors);
882 }
883 }
884
885 /// Equivalent to [`p.then_ref(f)`].
886 ///
887 /// [`p.then_ref(f)`]: ../trait.Parser.html#method.then
then_ref<Input, P, F, N>(p: P, f: F) -> ThenRef<P, F> where Input: Stream, F: FnMut(&P::Output) -> N, P: Parser<Input>, N: Parser<Input>,888 pub fn then_ref<Input, P, F, N>(p: P, f: F) -> ThenRef<P, F>
889 where
890 Input: Stream,
891 F: FnMut(&P::Output) -> N,
892 P: Parser<Input>,
893 N: Parser<Input>,
894 {
895 ThenRef(p, f)
896 }
897