#[macro_use]
mod macros;
pub mod bounded;
use std::iter::FromIterator;
use either::Either;
use crate::primitives::{IntoInner, Primitives};
use crate::types::{Input, ParseResult};
#[inline]
pub fn count<I: Input, T, E, F, U>(i: I, num: usize, p: F) -> ParseResult<I, T, E>
where
F: FnMut(I) -> ParseResult<I, U, E>,
T: FromIterator<U>,
{
bounded::many(i, num, p)
}
#[inline]
pub fn option<I: Input, T, E, F>(i: I, f: F, default: T) -> ParseResult<I, T, E>
where
F: FnOnce(I) -> ParseResult<I, T, E>,
{
let m = i.mark();
match f(i).into_inner() {
(b, Ok(d)) => b.ret(d),
(b, Err(_)) => b.restore(m).ret(default),
}
}
#[inline]
pub fn or<I: Input, T, E, F, G>(i: I, f: F, g: G) -> ParseResult<I, T, E>
where
F: FnOnce(I) -> ParseResult<I, T, E>,
G: FnOnce(I) -> ParseResult<I, T, E>,
{
let m = i.mark();
match f(i).into_inner() {
(b, Ok(d)) => b.ret(d),
(b, Err(_)) => g(b.restore(m)),
}
}
#[inline]
pub fn either<I, T, U, E, F, G>(i: I, f: F, g: G) -> ParseResult<I, Either<T, U>, E>
where
I: Input,
F: FnOnce(I) -> ParseResult<I, T, E>,
G: FnOnce(I) -> ParseResult<I, U, E>,
{
let m = i.mark();
match f(i).into_inner() {
(b, Ok(d)) => b.ret(Either::Left(d)),
(b, Err(_)) => g(b.restore(m)).map(Either::Right),
}
}
#[cfg(feature = "std")]
#[inline]
pub fn choice<I, T, E, R>(mut i: I, parsers: R) -> ParseResult<I, T, E>
where
I: Input,
R: IntoIterator<Item = Box<dyn FnMut(I) -> ParseResult<I, T, E>>>,
{
let mut ps = parsers.into_iter();
let mut m = i.mark();
let mut err = None;
loop {
if let Some(mut p) = ps.next() {
match p(i).into_inner() {
(b, Ok(t)) => return b.ret(t),
(b, Err(e)) => {
i = b.restore(m);
m = i.mark();
err = Some(e);
}
}
} else {
return i.err(err.expect("choice: Iterator cannot be empty"));
}
}
}
#[inline]
pub fn many<I: Input, T, E, F, U>(i: I, f: F) -> ParseResult<I, T, E>
where
F: FnMut(I) -> ParseResult<I, U, E>,
T: FromIterator<U>,
{
bounded::many(i, .., f)
}
#[inline]
pub fn many1<I: Input, T, E, F, U>(i: I, f: F) -> ParseResult<I, T, E>
where
F: FnMut(I) -> ParseResult<I, U, E>,
T: FromIterator<U>,
{
bounded::many(i, 1.., f)
}
#[inline]
pub fn sep_by<I: Input, T, E, R, F, U, N, V>(i: I, p: R, sep: F) -> ParseResult<I, T, E>
where
T: FromIterator<U>,
E: From<N>,
R: FnMut(I) -> ParseResult<I, U, E>,
F: FnMut(I) -> ParseResult<I, V, N>,
{
bounded::sep_by(i, .., p, sep)
}
#[inline]
pub fn sep_by1<I: Input, T, E, R, F, U, N, V>(i: I, p: R, sep: F) -> ParseResult<I, T, E>
where
T: FromIterator<U>,
E: From<N>,
R: FnMut(I) -> ParseResult<I, U, E>,
F: FnMut(I) -> ParseResult<I, V, N>,
{
bounded::sep_by(i, 1.., p, sep)
}
#[inline]
pub fn many_till<I: Input, T, E, R, F, U, N, V>(i: I, p: R, end: F) -> ParseResult<I, T, E>
where
T: FromIterator<U>,
E: From<N>,
R: FnMut(I) -> ParseResult<I, U, E>,
F: FnMut(I) -> ParseResult<I, V, N>,
{
bounded::many_till(i, .., p, end)
}
#[inline]
pub fn skip_many<I: Input, T, E, F>(i: I, f: F) -> ParseResult<I, (), E>
where
F: FnMut(I) -> ParseResult<I, T, E>,
{
bounded::skip_many(i, .., f)
}
#[inline]
pub fn skip_many1<I: Input, T, E, F>(i: I, f: F) -> ParseResult<I, (), E>
where
F: FnMut(I) -> ParseResult<I, T, E>,
{
bounded::skip_many(i, 1.., f)
}
#[inline]
pub fn matched_by<I: Input, T, E, F>(i: I, f: F) -> ParseResult<I, (I::Buffer, T), E>
where
F: FnOnce(I) -> ParseResult<I, T, E>,
{
let m = i.mark();
match f(i).into_inner() {
(mut b, Ok(t)) => {
let n = b.consume_from(m);
b.ret((n, t))
}
(b, Err(e)) => b.err(e),
}
}
#[inline]
pub fn look_ahead<I: Input, T, E, F>(i: I, f: F) -> ParseResult<I, T, E>
where
F: FnOnce(I) -> ParseResult<I, T, E>,
{
let m = i.mark();
match f(i).into_inner() {
(b, Ok(t)) => b.restore(m).ret(t),
(b, Err(t)) => b.restore(m).err(t),
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::parsers::{any, string, take, token, Error};
use crate::primitives::IntoInner;
use crate::types::{Input, ParseResult};
#[test]
fn option_test() {
assert_eq!(
option(&b""[..], any, b'-').into_inner(),
(&b""[..], Ok(b'-'))
);
assert_eq!(
option(&b"a"[..], any, b'-').into_inner(),
(&b""[..], Ok(b'a'))
);
assert_eq!(
option(&b""[..], |i| take(i, 2).map(ToOwned::to_owned), vec![]).into_inner(),
(&b""[..], Ok(vec![]))
);
assert_eq!(
option(&b"a"[..], |i| take(i, 2).map(ToOwned::to_owned), vec![]).into_inner(),
(&b"a"[..], Ok(vec![]))
);
assert_eq!(
option(&b"ab"[..], |i| take(i, 2).map(ToOwned::to_owned), vec![]).into_inner(),
(&b""[..], Ok(vec![b'a', b'b']))
);
assert_eq!(
option(&b"a"[..], |i| token(i, b' ').map_err(|_| "token_err"), b'-').into_inner(),
(&b"a"[..], Ok(b'-'))
);
}
#[test]
fn or_test() {
assert_eq!(
or(&b""[..], any, any).into_inner(),
(&b""[..], Err(Error::unexpected()))
);
assert_eq!(or(&b"a"[..], any, any).into_inner(), (&b""[..], Ok(b'a')));
assert_eq!(
or(&b"a"[..], |i| take(i, 2), |i| take(i, 1)).into_inner(),
(&b""[..], Ok(&b"a"[..]))
);
assert_eq!(
or(&b"ab"[..], |i| take(i, 2), |i| take(i, 1)).into_inner(),
(&b""[..], Ok(&b"ab"[..]))
);
assert_eq!(
or(&b"a"[..], |i| token(i, b'a'), |i| token(i, b'b')).into_inner(),
(&b""[..], Ok(b'a'))
);
assert_eq!(
or(&b"b"[..], |i| token(i, b'a'), |i| token(i, b'b')).into_inner(),
(&b""[..], Ok(b'b'))
);
assert_eq!(
or(
&b"c"[..],
|i| token(i, b'a').map_err(|_| "a err"),
|i| token(i, b'b').map_err(|_| "b err")
)
.into_inner(),
(&b"c"[..], Err("b err"))
);
}
#[test]
fn many_test() {
let r: (_, Result<Vec<u8>, _>) = many(&b""[..], |i| i.err("the error")).into_inner();
assert_eq!(r, (&b""[..], Ok(vec![])));
let r: (_, Result<Vec<u8>, _>) = many(&b"abc"[..], |i| i.err("the error")).into_inner();
assert_eq!(r, (&b"abc"[..], Ok(vec![])));
let r: (_, Result<Vec<_>, _>) = many(&b""[..], |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b""[..], Ok(vec![])));
let r: (_, Result<Vec<_>, _>) = many(&b"a"[..], |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b""[..], Ok(vec![b'a'])));
let r: (_, Result<Vec<_>, _>) = many(&b"aa"[..], |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b""[..], Ok(vec![b'a', b'a'])));
let r: (_, Result<Vec<_>, _>) = many(&b"bbb"[..], |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b"bbb"[..], Ok(vec![])));
let r: (_, Result<Vec<_>, _>) = many(&b"abb"[..], |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b"bb"[..], Ok(vec![b'a'])));
let r: (_, Result<Vec<_>, _>) = many(&b"aab"[..], |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b"b"[..], Ok(vec![b'a', b'a'])));
}
#[test]
fn many1_test() {
let r: (_, Result<Vec<u8>, _>) = many1(&b""[..], |i| i.err("the error")).into_inner();
assert_eq!(r, (&b""[..], Err("the error")));
let r: (_, Result<Vec<u8>, _>) = many1(&b"abc"[..], |i| i.err("the error")).into_inner();
assert_eq!(r, (&b"abc"[..], Err("the error")));
let r: (_, Result<Vec<_>, _>) = many1(&b""[..], |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b""[..], Err(Error::expected(b'a'))));
let r: (_, Result<Vec<_>, _>) = many1(&b"a"[..], |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b""[..], Ok(vec![b'a'])));
let r: (_, Result<Vec<_>, _>) = many1(&b"aa"[..], |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b""[..], Ok(vec![b'a', b'a'])));
let r: (_, Result<Vec<_>, _>) = many1(&b"bbb"[..], |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b"bbb"[..], Err(Error::expected(b'a'))));
let r: (_, Result<Vec<_>, _>) = many1(&b"abb"[..], |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b"bb"[..], Ok(vec![b'a'])));
let r: (_, Result<Vec<_>, _>) = many1(&b"aab"[..], |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b"b"[..], Ok(vec![b'a', b'a'])));
}
#[test]
fn count_test() {
let r: (_, Result<Vec<u8>, _>) = count(&b""[..], 3, |i| i.err("the error")).into_inner();
assert_eq!(r, (&b""[..], Err("the error")));
let r: (_, Result<Vec<_>, _>) = count(&b""[..], 3, |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b""[..], Err(Error::expected(b'a'))));
let r: (_, Result<Vec<_>, _>) = count(&b"a"[..], 3, |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b""[..], Err(Error::expected(b'a'))));
let r: (_, Result<Vec<_>, _>) = count(&b"aa"[..], 3, |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b""[..], Err(Error::expected(b'a'))));
let r: (_, Result<Vec<_>, _>) = count(&b"aaa"[..], 3, |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b""[..], Ok(vec![b'a', b'a', b'a'])));
let r: (_, Result<Vec<_>, _>) = count(&b"aaaa"[..], 3, |i| token(i, b'a')).into_inner();
assert_eq!(r, (&b"a"[..], Ok(vec![b'a', b'a', b'a'])));
}
#[test]
fn skip_many1_test() {
assert_eq!(
skip_many1(&b"bc"[..], |i| i.err::<(), _>("error")).into_inner(),
(&b"bc"[..], Err("error"))
);
assert_eq!(
skip_many1(&b"aabc"[..], |i| token(i, b'a')).into_inner(),
(&b"bc"[..], Ok(()))
);
assert_eq!(
skip_many1(&b"abc"[..], |i| token(i, b'a')).into_inner(),
(&b"bc"[..], Ok(()))
);
assert_eq!(
skip_many1(&b"bc"[..], |i| token(i, b'a')).into_inner(),
(&b"bc"[..], Err(Error::expected(b'a')))
);
assert_eq!(
skip_many1(&b""[..], |i| token(i, b'a')).into_inner(),
(&b""[..], Err(Error::expected(b'a')))
);
assert_eq!(
skip_many1(&b"aaa"[..], |i| token(i, b'a')).into_inner(),
(&b""[..], Ok(()))
);
}
#[test]
fn many_till_test() {
assert_eq!(
many_till(&b"abcd"[..], any, |i| token(i, b'c')).into_inner(),
(&b"d"[..], Ok(vec![b'a', b'b']))
);
let r: ParseResult<_, Vec<_>, _> = many_till(&b"abd"[..], any, |i| token(i, b'c'));
assert_eq!(r.into_inner(), (&b""[..], Err(Error::unexpected())));
let r: ParseResult<_, Vec<u8>, _> = many_till(
&b"abcd"[..],
|i| i.err(Error::expected(b'@')),
|i| token(i, b'c'),
);
assert_eq!(r.into_inner(), (&b"abcd"[..], Err(Error::expected(b'@'))));
let mut n = 0;
let r: ParseResult<_, Vec<_>, _> = many_till(
&b"abcd"[..],
|i| {
if n == 0 {
n += 1;
any(i).map_err(|_| Error::expected(b'i'))
} else {
i.err(Error::expected(b'@'))
}
},
|i| token(i, b'c'),
);
assert_eq!(r.into_inner(), (&b"bcd"[..], Err(Error::expected(b'@'))));
}
#[test]
fn matched_by_test() {
assert_eq!(
matched_by(&b"abc"[..], any).into_inner(),
(&b"bc"[..], Ok((&b"a"[..], b'a')))
);
assert_eq!(
matched_by(&b"abc"[..], |i| i.err::<(), _>("my error")).into_inner(),
(&b"abc"[..], Err("my error"))
);
assert_eq!(
matched_by(&b"abc"[..], |i| any(i)
.map_err(|_| "any error")
.then(|i| i.err::<(), _>("my error")))
.into_inner(),
(&b"bc"[..], Err("my error"))
);
assert_eq!(
matched_by(&b""[..], any).into_inner(),
(&b""[..], Err(Error::unexpected()))
);
}
#[test]
fn sep_by_test() {
assert_eq!(
sep_by(&b""[..], any, |i| token(i, b';')).into_inner(),
(&b""[..], Ok(vec![]))
);
assert_eq!(
sep_by(&b"a"[..], any, |i| token(i, b';')).into_inner(),
(&b""[..], Ok(vec![b'a']))
);
assert_eq!(
sep_by(&b"a;c"[..], any, |i| token(i, b';')).into_inner(),
(&b""[..], Ok(vec![b'a', b'c']))
);
assert_eq!(
sep_by(&b"a;c;"[..], any, |i| token(i, b';')).into_inner(),
(&b";"[..], Ok(vec![b'a', b'c']))
);
assert_eq!(
sep_by(&b"abc"[..], any, |i| token(i, b';')).into_inner(),
(&b"bc"[..], Ok(vec![b'a']))
);
assert_eq!(
sep_by(&b"a;bc"[..], any, |i| token(i, b';')).into_inner(),
(&b"c"[..], Ok(vec![b'a', b'b']))
);
assert_eq!(
sep_by(&b"abc"[..], any, |i| token(i, b';')).into_inner(),
(&b"bc"[..], Ok(vec![b'a']))
);
assert_eq!(
sep_by(&b"a;bc"[..], any, |i| token(i, b';')).into_inner(),
(&b"c"[..], Ok(vec![b'a', b'b']))
);
assert_eq!(
sep_by(&b"b"[..], |i| token(i, b'a'), |i| token(i, b';')).into_inner(),
(&b"b"[..], Ok(vec![]))
);
assert_eq!(
sep_by(&b"a--c-"[..], any, |i| string(i, b"--")).into_inner(),
(&b"-"[..], Ok(vec![b'a', b'c']))
);
let r: ParseResult<_, Vec<_>, _> = sep_by(&b""[..], any, |i| token(i, b';'));
assert_eq!(r.into_inner(), (&b""[..], Ok(vec![])));
let r: ParseResult<_, Vec<_>, _> = sep_by(&b"a"[..], any, |i| token(i, b';'));
assert_eq!(r.into_inner(), (&b""[..], Ok(vec![b'a'])));
let r: ParseResult<_, Vec<_>, _> = sep_by(&b"a;"[..], any, |i| token(i, b';'));
assert_eq!(r.into_inner(), (&b";"[..], Ok(vec![b'a'])));
let r: ParseResult<_, Vec<_>, _> = sep_by(&b"a;c"[..], any, |i| token(i, b';'));
assert_eq!(r.into_inner(), (&b""[..], Ok(vec![b'a', b'c'])));
let r: ParseResult<_, Vec<_>, _> = sep_by(&b"a;c;"[..], any, |i| token(i, b';'));
assert_eq!(r.into_inner(), (&b";"[..], Ok(vec![b'a', b'c'])));
let r: ParseResult<_, Vec<_>, _> = sep_by(&b"a--c-"[..], any, |i| string(i, b"--"));
assert_eq!(r.into_inner(), (&b"-"[..], Ok(vec![b'a', b'c'])));
let r: ParseResult<_, Vec<_>, _> =
sep_by(&b"aaa--a"[..], |i| string(i, b"aaa"), |i| string(i, b"--"));
assert_eq!(r.into_inner(), (&b"--a"[..], Ok(vec![&b"aaa"[..]])));
}
#[test]
fn sep_by1_test() {
let r: ParseResult<_, Vec<_>, _> = sep_by1(&b""[..], any, |i| token(i, b';'));
assert_eq!(r.into_inner(), (&b""[..], Err(Error::unexpected())));
let r: ParseResult<_, Vec<()>, _> = sep_by1(
&b"b"[..],
|i| i.err("my err"),
|i| token(i, b';').map_err(|_| "token_err"),
);
assert_eq!(r.into_inner(), (&b"b"[..], Err("my err")));
let r: ParseResult<_, Vec<_>, _> = sep_by1(&b""[..], any, |i| token(i, b';'));
assert_eq!(r.into_inner(), (&b""[..], Err(Error::unexpected())));
let r: ParseResult<_, Vec<_>, _> =
sep_by1(&b"b"[..], |i| token(i, b'a'), |i| token(i, b';'));
assert_eq!(r.into_inner(), (&b"b"[..], Err(Error::expected(b'a'))));
assert_eq!(
sep_by1(&b"a"[..], any, |i| token(i, b';')).into_inner(),
(&b""[..], Ok(vec![b'a']))
);
assert_eq!(
sep_by1(&b"a;c"[..], any, |i| token(i, b';')).into_inner(),
(&b""[..], Ok(vec![b'a', b'c']))
);
assert_eq!(
sep_by1(&b"a;c;"[..], any, |i| token(i, b';')).into_inner(),
(&b";"[..], Ok(vec![b'a', b'c']))
);
assert_eq!(
sep_by1(&b"a--c-"[..], any, |i| string(i, b"--")).into_inner(),
(&b"-"[..], Ok(vec![b'a', b'c']))
);
assert_eq!(
sep_by1(&b"abc"[..], any, |i| token(i, b';')).into_inner(),
(&b"bc"[..], Ok(vec![b'a']))
);
assert_eq!(
sep_by1(&b"a;bc"[..], any, |i| token(i, b';')).into_inner(),
(&b"c"[..], Ok(vec![b'a', b'b']))
);
assert_eq!(
sep_by1(&b"abc"[..], any, |i| token(i, b';')).into_inner(),
(&b"bc"[..], Ok(vec![b'a']))
);
assert_eq!(
sep_by1(&b"a;bc"[..], any, |i| token(i, b';')).into_inner(),
(&b"c"[..], Ok(vec![b'a', b'b']))
);
let r: ParseResult<_, Vec<_>, _> = sep_by1(&b""[..], any, |i| token(i, b';'));
assert_eq!(r.into_inner(), (&b""[..], Err(Error::unexpected())));
let r: ParseResult<_, Vec<_>, _> = sep_by1(&b"a"[..], any, |i| token(i, b';'));
assert_eq!(r.into_inner(), (&b""[..], Ok(vec![b'a'])));
let r: ParseResult<_, Vec<_>, _> = sep_by1(&b"a;"[..], any, |i| token(i, b';'));
assert_eq!(r.into_inner(), (&b";"[..], Ok(vec![b'a'])));
let r: ParseResult<_, Vec<_>, _> = sep_by1(&b"a;c"[..], any, |i| token(i, b';'));
assert_eq!(r.into_inner(), (&b""[..], Ok(vec![b'a', b'c'])));
let r: ParseResult<_, Vec<_>, _> = sep_by1(&b"a;c;"[..], any, |i| token(i, b';'));
assert_eq!(r.into_inner(), (&b";"[..], Ok(vec![b'a', b'c'])));
let r: ParseResult<_, Vec<_>, _> = sep_by1(&b"a--c-"[..], any, |i| string(i, b"--"));
assert_eq!(r.into_inner(), (&b"-"[..], Ok(vec![b'a', b'c'])));
let r: ParseResult<_, Vec<_>, _> =
sep_by1(&b"aaa--a"[..], |i| string(i, b"aaa"), |i| string(i, b"--"));
assert_eq!(r.into_inner(), (&b"--a"[..], Ok(vec![&b"aaa"[..]])));
}
#[test]
fn look_ahead_test() {
assert_eq!(
look_ahead(&b"abc"[..], any).into_inner(),
(&b"abc"[..], Ok(b'a'))
);
assert_eq!(
look_ahead(&b"a"[..], |i| string(i, b"abc")).into_inner(),
(&b"a"[..], Err(Error::expected(b'b')))
);
assert_eq!(
look_ahead(&b"aa"[..], |i| token(i, b'a')
.then(|i| token(i, b'b'))
.map_err(|_| "err"))
.into_inner(),
(&b"aa"[..], Err("err"))
);
}
#[cfg(feature = "std")]
mod choice_tests {
use crate::combinators::choice;
use crate::parsers::{token, Error};
use crate::primitives::IntoInner;
#[test]
fn choice_test() {
let v: Vec<Box<dyn FnMut(_) -> _>> =
vec![Box::new(|i| token(i, b'a')), Box::new(|i| token(i, b'b'))];
assert_eq!(choice(&b"abc"[..], v).into_inner(), (&b"bc"[..], Ok(b'a')));
let v: Vec<Box<dyn FnMut(_) -> _>> =
vec![Box::new(|i| token(i, b'a')), Box::new(|i| token(i, b'b'))];
assert_eq!(choice(&b"bca"[..], v).into_inner(), (&b"ca"[..], Ok(b'b')));
let v: Vec<Box<dyn FnMut(_) -> _>> =
vec![Box::new(|i| token(i, b'a')), Box::new(|i| token(i, b'b'))];
assert_eq!(
choice(&b"cab"[..], v).into_inner(),
(&b"cab"[..], Err(Error::expected(b'b')))
);
}
#[test]
#[should_panic]
fn choice_empty() {
assert_eq!(
choice::<_, (), (), _>(&b"abc"[..], vec![]).into_inner(),
(&b"abc"[..], Err(()))
);
}
}
}