Skip to content

Commit

Permalink
feat: Add the choice! macro
Browse files Browse the repository at this point in the history
This macro should give a cleaner way of writing multiple alternative parsers and may also result in faster code.
  • Loading branch information
Marwes committed Feb 3, 2017
1 parent 501322b commit 6f2cec6
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
31 changes: 30 additions & 1 deletion src/combinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ pub fn count<F, P>(count: usize, parser: P) -> Count<F, P>
}

/// Takes an array of parsers and tries to apply them each in order.
/// Fails if all parsers fails or if an applied parser consumes input before failing.
/// Fails if all the parsers fails or if an applied parser consumes input before failing.
///
/// ```
/// # extern crate combine;
Expand Down Expand Up @@ -598,6 +598,35 @@ pub fn choice<S, P>(ps: S) -> Choice<S, P>
Choice(ps, PhantomData)
}

/// Takes a number of parsers and tries to apply them each in order.
/// Fails if all the parsers fails or if an applied parser consumes input before failing.
///
/// ```
/// # #[macro_use]
/// # extern crate combine;
/// # use combine::*;
/// # use combine::char::{digit, letter, string};
/// # use combine::primitives::Error;
/// # fn main() {
/// let mut parser = choice!(
/// many1(digit()),
/// string("let").map(|s| s.to_string()),
/// many1(letter()));
/// assert_eq!(parser.parse("let"), Ok(("let".to_string(), "")));
/// assert_eq!(parser.parse("123abc"), Ok(("123".to_string(), "abc")));
/// assert!(parser.parse(":123").is_err());
/// # }
/// ```
#[macro_export]
macro_rules! choice {
($first : expr) => {
$first
};
($first : expr, $($rest : expr),+) => {
$first.or(choice!($($rest),+))
}
}

#[derive(Clone)]
pub struct Unexpected<I>(Info<I::Item, I::Range>, PhantomData<fn(I) -> I>) where I: Stream;
impl<I> Parser for Unexpected<I>
Expand Down
3 changes: 3 additions & 0 deletions src/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1319,6 +1319,9 @@ pub trait Parser {
/// Returns a parser which attempts to parse using `self`. If `self` fails without consuming any
/// input it tries to consume the same input using `p`.
///
/// If you are looking to chain 3 or more parsers using `or` you may consider using the
/// `choice!` macro instead, which can be clearer and may result in a faster parser.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
Expand Down

0 comments on commit 6f2cec6

Please sign in to comment.