#[macro_use]
mod macros;
pub mod bounded;
use std::iter::FromIterator;
use either::Either;
use types::{
Input,
ParseResult,
};
use primitives::{
IntoInner,
Primitives,
};
#[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),
}
}
#[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 types::{Input, ParseResult};
use primitives::IntoInner;
use super::*;
use parsers::{Error, any, take, token, string};
#[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")));
}
}