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