Skip to content

Commit

Permalink
Merge pull request #298 from epage/alt
Browse files Browse the repository at this point in the history
feat(comb): Allow arrays as input to `alt`
  • Loading branch information
epage authored Jul 30, 2023
2 parents c768921 + 3bdd5ec commit 114e3ff
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/combinator/branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,26 @@ pub fn permutation<I: Stream, O, E: ParserError<I>, List: Permutation<I, O, E>>(
trace("permutation", move |i: &mut I| l.permutation(i))
}

impl<const N: usize, I: Stream, O, E: ParserError<I>, P: Parser<I, O, E>> Alt<I, O, E> for [P; N] {
fn choice(&mut self, input: &mut I) -> PResult<O, E> {
let mut error = None;

let start = input.checkpoint();
for branch in self {
input.reset(start.clone());
match branch.parse_next(input) {
Err(ErrMode::Backtrack(e)) => error = Some(e),
res => return res,
}
}

match error {
Some(e) => Err(ErrMode::Backtrack(e.append(input, ErrorKind::Alt))),
None => Err(ErrMode::assert(input, "`alt` needs at least one parser")),
}
}
}

macro_rules! alt_trait(
($first:ident $second:ident $($id: ident)+) => (
alt_trait!(__impl $first $second; $($id)+);
Expand Down
23 changes: 23 additions & 0 deletions src/combinator/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::stream::Stream;
use crate::token::take;
use crate::unpeek;
use crate::IResult;
use crate::PResult;
use crate::Parser;
use crate::Partial;

Expand Down Expand Up @@ -648,6 +649,28 @@ fn alt_incomplete() {
);
}

#[test]
fn alt_array() {
fn alt1<'i>(i: &mut &'i [u8]) -> PResult<&'i [u8]> {
alt(["a", "bc", "def"]).parse_next(i)
}

let i = &b"a"[..];
assert_eq!(alt1.parse_peek(i), Ok((&b""[..], (&b"a"[..]))));

let i = &b"bc"[..];
assert_eq!(alt1.parse_peek(i), Ok((&b""[..], (&b"bc"[..]))));

let i = &b"defg"[..];
assert_eq!(alt1.parse_peek(i), Ok((&b"g"[..], (&b"def"[..]))));

let i = &b"z"[..];
assert_eq!(
alt1.parse_peek(i),
Err(ErrMode::Backtrack(error_position!(&i, ErrorKind::Tag)))
);
}

#[test]
fn permutation_test() {
#[allow(clippy::type_complexity)]
Expand Down

0 comments on commit 114e3ff

Please sign in to comment.