futures_await_synom/
lib.rs

1//! Adapted from [`nom`](https://github.com/Geal/nom) by removing the
2//! `IPResult::Incomplete` variant which:
3//!
4//! - we don't need,
5//! - is an unintuitive footgun when working with non-streaming use cases, and
6//! - more than doubles compilation time.
7//!
8//! ## Whitespace handling strategy
9//!
10//! As (sy)nom is a parser combinator library, the parsers provided here and
11//! that you implement yourself are all made up of successively more primitive
12//! parsers, eventually culminating in a small number of fundamental parsers
13//! that are implemented in Rust. Among these are `punct!` and `keyword!`.
14//!
15//! All synom fundamental parsers (those not combined out of other parsers)
16//! should be written to skip over leading whitespace in their input. This way,
17//! as long as every parser eventually boils down to some combination of
18//! fundamental parsers, we get correct whitespace handling at all levels for
19//! free.
20//!
21//! For our use case, this strategy is a huge improvement in usability,
22//! correctness, and compile time over nom's `ws!` strategy.
23
24extern crate proc_macro;
25extern crate proc_macro2;
26
27#[cfg(feature = "printing")]
28extern crate futures_await_quote as quote;
29
30#[doc(hidden)]
31pub use proc_macro2::{TokenTree, TokenStream};
32
33use std::convert::From;
34use std::error::Error;
35use std::fmt;
36
37#[cfg(feature = "parsing")]
38#[doc(hidden)]
39pub mod helper;
40
41pub mod delimited;
42pub mod tokens;
43pub mod span;
44pub mod cursor;
45
46pub use cursor::{SynomBuffer, Cursor};
47
48/// The result of a parser
49pub type PResult<'a, O> = Result<(Cursor<'a>, O), ParseError>;
50
51/// An error with a default error message.
52///
53/// NOTE: We should provide better error messages in the future.
54pub fn parse_error<O>() -> PResult<'static, O> {
55    Err(ParseError(None))
56}
57
58pub trait Synom: Sized {
59    fn parse(input: Cursor) -> PResult<Self>;
60
61    fn description() -> Option<&'static str> {
62        None
63    }
64}
65
66#[derive(Debug)]
67pub struct ParseError(Option<String>);
68
69impl Error for ParseError {
70    fn description(&self) -> &str {
71        match self.0 {
72            Some(ref desc) => desc,
73            None => "failed to parse",
74        }
75    }
76}
77
78impl fmt::Display for ParseError {
79    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80        <str as fmt::Display>::fmt(self.description(), f)
81    }
82}
83
84impl From<proc_macro2::LexError> for ParseError {
85    fn from(_: proc_macro2::LexError) -> ParseError {
86        ParseError(Some("error while lexing input string".to_owned()))
87    }
88}
89
90impl From<proc_macro::LexError> for ParseError {
91    fn from(_: proc_macro::LexError) -> ParseError {
92        ParseError(Some("error while lexing input string".to_owned()))
93    }
94}
95
96impl ParseError {
97    // For syn use only. Not public API.
98    #[doc(hidden)]
99    pub fn new<T: Into<String>>(msg: T) -> Self {
100        ParseError(Some(msg.into()))
101    }
102}
103
104impl Synom for TokenStream {
105    fn parse(input: Cursor) -> PResult<Self> {
106        Ok((Cursor::empty(), input.token_stream()))
107    }
108}
109
110/// Define a function from a parser combination.
111///
112/// - **Syntax:** `named!(NAME -> TYPE, PARSER)` or `named!(pub NAME -> TYPE, PARSER)`
113///
114/// ```rust
115/// # extern crate syn;
116/// # #[macro_use] extern crate synom;
117/// # use syn::Ty;
118/// # use synom::delimited::Delimited;
119/// # use synom::tokens::Comma;
120/// // One or more Rust types separated by commas.
121/// named!(pub comma_separated_types -> Delimited<Ty, Comma>,
122///     call!(Delimited::parse_separated_nonempty)
123/// );
124/// # fn main() {}
125/// ```
126#[macro_export]
127macro_rules! named {
128    ($name:ident -> $o:ty, $submac:ident!( $($args:tt)* )) => {
129        fn $name(i: $crate::Cursor) -> $crate::PResult<$o> {
130            $submac!(i, $($args)*)
131        }
132    };
133
134    (pub $name:ident -> $o:ty, $submac:ident!( $($args:tt)* )) => {
135        pub fn $name(i: $crate::Cursor) -> $crate::PResult<$o> {
136            $submac!(i, $($args)*)
137        }
138    };
139
140    // These two variants are for defining named parsers which have custom
141    // arguments, and are called with `call!()`
142    ($name:ident($($params:tt)*) -> $o:ty, $submac:ident!( $($args:tt)* )) => {
143        fn $name(i: $crate::Cursor, $($params)*) -> $crate::PResult<$o> {
144            $submac!(i, $($args)*)
145        }
146    };
147
148    (pub $name:ident($($params:tt)*) -> $o:ty, $submac:ident!( $($args:tt)* )) => {
149        pub fn $name(i: $crate::Cursor, $($params)*) -> $crate::PResult<$o> {
150            $submac!(i, $($args)*)
151        }
152    };
153}
154
155/// Invoke the given parser function with the passed in arguments.
156///
157/// - **Syntax:** `call!(FUNCTION, ARGS...)`
158///
159///   where the signature of the function is `fn(&[U], ARGS...) -> IPResult<&[U], T>`
160/// - **Output:** `T`, the result of invoking the function `FUNCTION`
161#[macro_export]
162macro_rules! call {
163    ($i:expr, $fun:expr $(, $args:expr)*) => {
164        $fun($i $(, $args)*)
165    };
166}
167
168/// Transform the result of a parser by applying a function or closure.
169///
170/// - **Syntax:** `map!(THING, FN)`
171/// - **Output:** the return type of function FN applied to THING
172///
173/// ```rust
174/// extern crate syn;
175/// #[macro_use] extern crate synom;
176///
177/// use syn::{Expr, ExprIf};
178///
179/// fn get_cond(if_: ExprIf) -> Expr {
180///     *if_.cond
181/// }
182///
183/// // Parses an `if` statement but returns the condition part only.
184/// named!(if_condition -> Expr,
185///     map!(syn!(ExprIf), get_cond)
186/// );
187///
188/// // Or equivalently:
189/// named!(if_condition2 -> Expr,
190///     map!(syn!(ExprIf), |if_| *if_.cond)
191/// );
192/// #
193/// # fn main() {}
194/// ```
195#[macro_export]
196macro_rules! map {
197    ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => {
198        match $submac!($i, $($args)*) {
199            ::std::result::Result::Err(err) =>
200                ::std::result::Result::Err(err),
201            ::std::result::Result::Ok((i, o)) =>
202                ::std::result::Result::Ok((i, $crate::invoke($g, o))),
203        }
204    };
205
206    ($i:expr, $f:expr, $g:expr) => {
207        map!($i, call!($f), $g)
208    };
209}
210
211// Somehow this helps with type inference in `map!`.
212//
213// Not public API.
214#[doc(hidden)]
215pub fn invoke<T, R, F: FnOnce(T) -> R>(f: F, t: T) -> R {
216    f(t)
217}
218
219/// Parses successfully if the given parser fails to parse. Does not consume any
220/// of the input.
221///
222/// - **Syntax:** `not!(THING)`
223/// - **Output:** `()`
224#[macro_export]
225macro_rules! not {
226    ($i:expr, $submac:ident!( $($args:tt)* )) => {
227        match $submac!($i, $($args)*) {
228            ::std::result::Result::Ok(_) => $crate::parse_error(),
229            ::std::result::Result::Err(_) =>
230                ::std::result::Result::Ok(($i, ())),
231        }
232    };
233}
234
235/// Conditionally execute the given parser.
236///
237/// If you are familiar with nom, this is nom's `cond_with_error` parser.
238///
239/// - **Syntax:** `cond!(CONDITION, THING)`
240/// - **Output:** `Some(THING)` if the condition is true, else `None`
241#[macro_export]
242macro_rules! cond {
243    ($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => {
244        if $cond {
245            match $submac!($i, $($args)*) {
246                ::std::result::Result::Ok((i, o)) =>
247                    ::std::result::Result::Ok((i, ::std::option::Option::Some(o))),
248                ::std::result::Result::Err(x) => ::std::result::Result::Err(x),
249            }
250        } else {
251            ::std::result::Result::Ok(($i, ::std::option::Option::None))
252        }
253    };
254
255    ($i:expr, $cond:expr, $f:expr) => {
256        cond!($i, $cond, call!($f))
257    };
258}
259
260/// Fail to parse if condition is false, otherwise parse the given parser.
261///
262/// This is typically used inside of `option!` or `alt!`.
263///
264/// - **Syntax:** `cond_reduce!(CONDITION, THING)`
265/// - **Output:** `THING`
266#[macro_export]
267macro_rules! cond_reduce {
268    ($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => {
269        if $cond {
270            $submac!($i, $($args)*)
271        } else {
272            $crate::parse_error()
273        }
274    };
275
276    ($i:expr, $cond:expr, $f:expr) => {
277        cond_reduce!($i, $cond, call!($f))
278    };
279}
280
281/// Parse two things, returning the value of the first.
282///
283/// - **Syntax:** `terminated!(THING, AFTER)`
284/// - **Output:** `THING`
285///
286/// ```rust
287/// extern crate syn;
288/// #[macro_use] extern crate synom;
289///
290/// use syn::Expr;
291/// use synom::tokens::Pound;
292///
293/// // An expression terminated by ##.
294/// named!(expr_pound_pound -> Expr,
295///     terminated!(syn!(Expr), tuple!(syn!(Pound), syn!(Pound)))
296/// );
297///
298/// # fn main() {}
299/// ```
300#[macro_export]
301macro_rules! terminated {
302    ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => {
303        match tuple!($i, $submac!($($args)*), $submac2!($($args2)*)) {
304            ::std::result::Result::Ok((i, (o, _))) =>
305                ::std::result::Result::Ok((i, o)),
306            ::std::result::Result::Err(err) =>
307                ::std::result::Result::Err(err),
308        }
309    };
310
311    ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => {
312        terminated!($i, $submac!($($args)*), call!($g))
313    };
314
315    ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => {
316        terminated!($i, call!($f), $submac!($($args)*))
317    };
318
319    ($i:expr, $f:expr, $g:expr) => {
320        terminated!($i, call!($f), call!($g))
321    };
322}
323
324/// Parse zero or more values using the given parser.
325///
326/// - **Syntax:** `many0!(THING)`
327/// - **Output:** `Vec<THING>`
328///
329/// You may also be looking for:
330///
331/// - `call!(Delimited::parse_separated)` - zero or more values with separator
332/// - `call!(Delimited::parse_separated_nonempty)` - one or more values
333/// - `call!(Delimited::parse_terminated)` - zero or more, allows trailing separator
334///
335/// ```rust
336/// extern crate syn;
337/// #[macro_use] extern crate synom;
338///
339/// use syn::Item;
340///
341/// named!(items -> Vec<Item>, many0!(syn!(Item)));
342///
343/// # fn main() {}
344#[macro_export]
345macro_rules! many0 {
346    ($i:expr, $submac:ident!( $($args:tt)* )) => {{
347        let ret;
348        let mut res   = ::std::vec::Vec::new();
349        let mut input = $i;
350
351        loop {
352            if input.eof() {
353                ret = ::std::result::Result::Ok((input, res));
354                break;
355            }
356
357            match $submac!(input, $($args)*) {
358                ::std::result::Result::Err(_) => {
359                    ret = ::std::result::Result::Ok((input, res));
360                    break;
361                }
362                ::std::result::Result::Ok((i, o)) => {
363                    // loop trip must always consume (otherwise infinite loops)
364                    if i == input {
365                        ret = $crate::parse_error();
366                        break;
367                    }
368
369                    res.push(o);
370                    input = i;
371                }
372            }
373        }
374
375        ret
376    }};
377
378    ($i:expr, $f:expr) => {
379        $crate::many0($i, $f)
380    };
381}
382
383// Improve compile time by compiling this loop only once per type it is used
384// with.
385//
386// Not public API.
387#[doc(hidden)]
388pub fn many0<'a, T>(mut input: Cursor, f: fn(Cursor) -> PResult<T>) -> PResult<Vec<T>> {
389    let mut res = Vec::new();
390
391    loop {
392        if input.eof() {
393            return Ok((input, res));
394        }
395
396        match f(input) {
397            Err(_) => {
398                return Ok((input, res));
399            }
400            Ok((i, o)) => {
401                // loop trip must always consume (otherwise infinite loops)
402                if i == input {
403                    return parse_error();
404                }
405
406                res.push(o);
407                input = i;
408            }
409        }
410    }
411}
412
413/// Parse a value without consuming it from the input data.
414///
415/// - **Syntax:** `peek!(THING)`
416/// - **Output:** `THING`
417///
418/// ```rust
419/// extern crate syn;
420/// #[macro_use] extern crate synom;
421///
422/// use syn::{Expr, Ident};
423///
424/// // Parse an expression that begins with an identifier.
425/// named!(ident_expr -> (Ident, Expr),
426///     tuple!(peek!(syn!(Ident)), syn!(Expr))
427/// );
428///
429/// # fn main() {}
430/// ```
431#[macro_export]
432macro_rules! peek {
433    ($i:expr, $submac:ident!( $($args:tt)* )) => {
434        match $submac!($i, $($args)*) {
435            ::std::result::Result::Ok((_, o)) => ::std::result::Result::Ok(($i, o)),
436            ::std::result::Result::Err(err) => ::std::result::Result::Err(err),
437        }
438    };
439
440    ($i:expr, $f:expr) => {
441        peek!($i, call!($f))
442    };
443}
444
445/// Pattern-match the result of a parser to select which other parser to run.
446///
447/// - **Syntax:** `switch!(TARGET, PAT1 => THEN1 | PAT2 => THEN2 | ...)`
448/// - **Output:** `T`, the return type of `THEN1` and `THEN2` and ...
449///
450/// ```rust
451/// extern crate syn;
452/// #[macro_use] extern crate synom;
453///
454/// use syn::{Ident, Ty};
455/// use synom::tokens::*;
456///
457/// #[derive(Debug)]
458/// enum UnitType {
459///     Struct {
460///         name: Ident,
461///     },
462///     Enum {
463///         name: Ident,
464///         variant: Ident,
465///     },
466/// }
467///
468/// // Parse a unit struct or enum: either `struct S;` or `enum E { V }`.
469/// named!(unit_type -> UnitType, do_parse!(
470///     which: alt!(
471///         syn!(Struct) => { |_| 0 }
472///         |
473///         syn!(Enum) => { |_| 1 }
474///     ) >>
475///     id: syn!(Ident) >>
476///     item: switch!(value!(which),
477///         0 => map!(
478///             syn!(Semi),
479///             move |_| UnitType::Struct {
480///                 name: id,
481///             }
482///         )
483///         |
484///         1 => map!(
485///             braces!(syn!(Ident)),
486///             move |(variant, _)| UnitType::Enum {
487///                 name: id,
488///                 variant: variant,
489///             }
490///         )
491///     ) >>
492///     (item)
493/// ));
494///
495/// # fn main() {}
496/// ```
497#[macro_export]
498macro_rules! switch {
499    ($i:expr, $submac:ident!( $($args:tt)* ), $($p:pat => $subrule:ident!( $($args2:tt)* ))|* ) => {
500        match $submac!($i, $($args)*) {
501            ::std::result::Result::Err(err) => ::std::result::Result::Err(err),
502            ::std::result::Result::Ok((i, o)) => match o {
503                $(
504                    $p => $subrule!(i, $($args2)*),
505                )*
506                _ => $crate::parse_error(),
507            }
508        }
509    };
510}
511
512
513/// Produce the given value without parsing anything. Useful as an argument to
514/// `switch!`.
515///
516/// - **Syntax:** `value!(VALUE)`
517/// - **Output:** `VALUE`
518///
519/// ```rust
520/// extern crate syn;
521/// #[macro_use] extern crate synom;
522///
523/// use syn::{Ident, Ty};
524/// use synom::tokens::*;
525///
526/// #[derive(Debug)]
527/// enum UnitType {
528///     Struct {
529///         name: Ident,
530///     },
531///     Enum {
532///         name: Ident,
533///         variant: Ident,
534///     },
535/// }
536///
537/// // Parse a unit struct or enum: either `struct S;` or `enum E { V }`.
538/// named!(unit_type -> UnitType, do_parse!(
539///     which: alt!(
540///         syn!(Struct) => { |_| 0 }
541///         |
542///         syn!(Enum) => { |_| 1 }
543///     ) >>
544///     id: syn!(Ident) >>
545///     item: switch!(value!(which),
546///         0 => map!(
547///             syn!(Semi),
548///             move |_| UnitType::Struct {
549///                 name: id,
550///             }
551///         )
552///         |
553///         1 => map!(
554///             braces!(syn!(Ident)),
555///             move |(variant, _)| UnitType::Enum {
556///                 name: id,
557///                 variant: variant,
558///             }
559///         )
560///     ) >>
561///     (item)
562/// ));
563///
564/// # fn main() {}
565/// ```
566#[macro_export]
567macro_rules! value {
568    ($i:expr, $res:expr) => {
569        ::std::result::Result::Ok(($i, $res))
570    };
571}
572
573/// Run a series of parsers and produce all of the results in a tuple.
574///
575/// - **Syntax:** `tuple!(A, B, C, ...)`
576/// - **Output:** `(A, B, C, ...)`
577///
578/// ```rust
579/// extern crate syn;
580/// #[macro_use] extern crate synom;
581///
582/// use syn::Ty;
583///
584/// named!(two_types -> (Ty, Ty), tuple!(syn!(Ty), syn!(Ty)));
585///
586/// # fn main() {}
587/// ```
588#[macro_export]
589macro_rules! tuple {
590    ($i:expr, $($rest:tt)*) => {
591        tuple_parser!($i, (), $($rest)*)
592    };
593}
594
595/// Internal parser, do not use directly.
596#[doc(hidden)]
597#[macro_export]
598macro_rules! tuple_parser {
599    ($i:expr, ($($parsed:tt),*), $e:ident, $($rest:tt)*) => {
600        tuple_parser!($i, ($($parsed),*), call!($e), $($rest)*)
601    };
602
603    ($i:expr, (), $submac:ident!( $($args:tt)* ), $($rest:tt)*) => {
604        match $submac!($i, $($args)*) {
605            ::std::result::Result::Err(err) =>
606                ::std::result::Result::Err(err),
607            ::std::result::Result::Ok((i, o)) =>
608                tuple_parser!(i, (o), $($rest)*),
609        }
610    };
611
612    ($i:expr, ($($parsed:tt)*), $submac:ident!( $($args:tt)* ), $($rest:tt)*) => {
613        match $submac!($i, $($args)*) {
614            ::std::result::Result::Err(err) =>
615                ::std::result::Result::Err(err),
616            ::std::result::Result::Ok((i, o)) =>
617                tuple_parser!(i, ($($parsed)* , o), $($rest)*),
618        }
619    };
620
621    ($i:expr, ($($parsed:tt),*), $e:ident) => {
622        tuple_parser!($i, ($($parsed),*), call!($e))
623    };
624
625    ($i:expr, (), $submac:ident!( $($args:tt)* )) => {
626        $submac!($i, $($args)*)
627    };
628
629    ($i:expr, ($($parsed:expr),*), $submac:ident!( $($args:tt)* )) => {
630        match $submac!($i, $($args)*) {
631            ::std::result::Result::Err(err) =>
632                ::std::result::Result::Err(err),
633            ::std::result::Result::Ok((i, o)) =>
634                ::std::result::Result::Ok((i, ($($parsed),*, o))),
635        }
636    };
637
638    ($i:expr, ($($parsed:expr),*)) => {
639        ::std::result::Result::Ok(($i, ($($parsed),*)))
640    };
641}
642
643/// Run a series of parsers, returning the result of the first one which
644/// succeeds.
645///
646/// Optionally allows for the result to be transformed.
647///
648/// - **Syntax:** `alt!(THING1 | THING2 => { FUNC } | ...)`
649/// - **Output:** `T`, the return type of `THING1` and `FUNC(THING2)` and ...
650///
651/// ```rust
652/// extern crate syn;
653/// #[macro_use] extern crate synom;
654///
655/// use syn::Ident;
656/// use synom::tokens::Bang;
657///
658/// named!(ident_or_bang -> Ident,
659///     alt!(
660///         syn!(Ident)
661///         |
662///         syn!(Bang) => { |_| "BANG".into() }
663///     )
664/// );
665///
666/// # fn main() {}
667/// ```
668#[macro_export]
669macro_rules! alt {
670    ($i:expr, $e:ident | $($rest:tt)*) => {
671        alt!($i, call!($e) | $($rest)*)
672    };
673
674    ($i:expr, $subrule:ident!( $($args:tt)*) | $($rest:tt)*) => {
675        match $subrule!($i, $($args)*) {
676            res @ ::std::result::Result::Ok(_) => res,
677            _ => alt!($i, $($rest)*)
678        }
679    };
680
681    ($i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr } | $($rest:tt)+) => {
682        match $subrule!($i, $($args)*) {
683            ::std::result::Result::Ok((i, o)) =>
684                ::std::result::Result::Ok((i, $gen(o))),
685            ::std::result::Result::Err(_) => alt!($i, $($rest)*),
686        }
687    };
688
689    ($i:expr, $e:ident => { $gen:expr } | $($rest:tt)*) => {
690        alt!($i, call!($e) => { $gen } | $($rest)*)
691    };
692
693    ($i:expr, $e:ident => { $gen:expr }) => {
694        alt!($i, call!($e) => { $gen })
695    };
696
697    ($i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr }) => {
698        match $subrule!($i, $($args)*) {
699            ::std::result::Result::Ok((i, o)) =>
700                ::std::result::Result::Ok((i, $gen(o))),
701            ::std::result::Result::Err(err) =>
702                ::std::result::Result::Err(err),
703        }
704    };
705
706    ($i:expr, $e:ident) => {
707        alt!($i, call!($e))
708    };
709
710    ($i:expr, $subrule:ident!( $($args:tt)*)) => {
711        $subrule!($i, $($args)*)
712    };
713}
714
715/// Run a series of parsers, one after another, optionally assigning the results
716/// a name. Fail if any of the parsers fails.
717///
718/// Produces the result of evaluating the final expression in parentheses with
719/// all of the previously named results bound.
720///
721/// - **Syntax:** `do_parse!(name: THING1 >> THING2 >> (RESULT))`
722/// - **Output:** `RESULT`
723///
724/// ```rust
725/// extern crate syn;
726/// #[macro_use] extern crate synom;
727/// extern crate proc_macro2;
728///
729/// use syn::{Ident, TokenTree};
730/// use synom::tokens::{Bang, Paren};
731/// use proc_macro2::TokenStream;
732///
733/// // Parse a macro invocation like `stringify!($args)`.
734/// named!(simple_mac -> (Ident, (TokenStream, Paren)), do_parse!(
735///     name: syn!(Ident) >>
736///     syn!(Bang) >>
737///     body: parens!(syn!(TokenStream)) >>
738///     (name, body)
739/// ));
740///
741/// # fn main() {}
742/// ```
743#[macro_export]
744macro_rules! do_parse {
745    ($i:expr, ( $($rest:expr),* )) => {
746        ::std::result::Result::Ok(($i, ( $($rest),* )))
747    };
748
749    ($i:expr, $e:ident >> $($rest:tt)*) => {
750        do_parse!($i, call!($e) >> $($rest)*)
751    };
752
753    ($i:expr, $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => {
754        match $submac!($i, $($args)*) {
755            ::std::result::Result::Err(err) =>
756                ::std::result::Result::Err(err),
757            ::std::result::Result::Ok((i, _)) =>
758                do_parse!(i, $($rest)*),
759        }
760    };
761
762    ($i:expr, $field:ident : $e:ident >> $($rest:tt)*) => {
763        do_parse!($i, $field: call!($e) >> $($rest)*)
764    };
765
766    ($i:expr, $field:ident : $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => {
767        match $submac!($i, $($args)*) {
768            ::std::result::Result::Err(err) =>
769                ::std::result::Result::Err(err),
770            ::std::result::Result::Ok((i, o)) => {
771                let $field = o;
772                do_parse!(i, $($rest)*)
773            },
774        }
775    };
776
777    ($i:expr, mut $field:ident : $e:ident >> $($rest:tt)*) => {
778        do_parse!($i, mut $field: call!($e) >> $($rest)*)
779    };
780
781    ($i:expr, mut $field:ident : $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => {
782        match $submac!($i, $($args)*) {
783            ::std::result::Result::Err(err) =>
784                ::std::result::Result::Err(err),
785            ::std::result::Result::Ok((i, o)) => {
786                let mut $field = o;
787                do_parse!(i, $($rest)*)
788            },
789        }
790    };
791}
792
793#[macro_export]
794macro_rules! input_end {
795    ($i:expr,) => {
796        $crate::input_end($i)
797    };
798}
799
800// Not a public API
801#[doc(hidden)]
802pub fn input_end(input: Cursor) -> PResult<'static, &'static str> {
803    if input.eof() {
804        Ok((Cursor::empty(), ""))
805    } else {
806        parse_error()
807    }
808}