pear 0.0.9

A pear is a fruit.
Documentation
use {Input, Length, ParseResult, Expected};
use result::error;
use ParseResult::*;

#[inline(always)]
fn advance_and<I: Input, T>(input: &mut I, num: usize, out: T) -> ParseResult<I, T> {
    input.advance(num);
    Done(out)
}

#[inline]
pub fn eat<I: Input>(input: &mut I, token: I::Token) -> ParseResult<I, I::Token> {
    match input.peek() {
        Some(peeked) if peeked == token => advance_and(input, 1, token),
        t@Some(_) | t@None => error("eat", Expected::Token(Some(token), t)),
    }
}

#[inline]
pub fn eat_if<I: Input, F>(input: &mut I, cond: F) -> ParseResult<I, I::Token>
    where F: Fn(I::Token) -> bool
{
    match input.peek() {
        Some(peeked) if cond(peeked) => advance_and(input, 1, peeked),
        t@Some(_) | t@None => error("eat_if", Expected::Token(None, t)),
    }
}

#[inline]
pub fn eat_slice<I: Input>(input: &mut I, slice: I::Slice) -> ParseResult<I, I::Slice> {
    let len = slice.len();
    match input.peek_slice(slice) {
        Some(peeked) if peeked == slice => advance_and(input, len, slice),
        t@Some(_) | t@None => error("eat_slice", Expected::Slice(Some(slice), t)),
    }
}

#[inline]
pub fn eat_any<I: Input>(input: &mut I) -> ParseResult<I, I::Token> {
    match input.peek() {
        Some(peeked) => advance_and(input, 1, peeked),
        None => error("eat_any", Expected::Token(None, None)),
    }
}

#[inline]
pub fn peek<I: Input>(input: &mut I, token: I::Token) -> ParseResult<I, I::Token> {
    match input.peek() {
        Some(peeked) if peeked == token => Done(token),
        t@Some(_) | t@None => error("eat", Expected::Token(Some(token), t)),
    }
}

#[inline]
pub fn peek_if<I: Input, F>(input: &mut I, cond: F) -> ParseResult<I, I::Token>
    where F: Fn(I::Token) -> bool
{
    match input.peek() {
        Some(peeked) if cond(peeked) => Done(peeked),
        t@Some(_) | t@None => error("peek_id", Expected::Token(None, t)),
    }
}

#[inline]
pub fn peek_slice<I: Input>(input: &mut I, slice: I::Slice) -> ParseResult<I, I::Slice> {
    match input.peek_slice(slice) {
        Some(peeked) if peeked == slice => Done(slice),
        t@Some(_) | t@None => error("peek_slice", Expected::Slice(Some(slice), t)),
    }
}

#[inline]
pub fn skip_while<I: Input, F>(input: &mut I, condition: F) -> ParseResult<I, ()>
    where F: FnMut(I::Token) -> bool
{
    input.skip_many(condition);
    Done(())
}

#[inline]
pub fn take_some_while<I: Input, F>(input: &mut I, condition: F) -> ParseResult<I, I::Many>
    where F: FnMut(I::Token) -> bool
{
    let value = input.take_many(condition);
    if value.len() == 0 {
        return error("take_some_while", Expected::Token(None, None));
    }

    Done(value)
}

#[inline(always)]
pub fn take_while<I: Input, F>(input: &mut I, condition: F) -> ParseResult<I, I::Many>
    where F: FnMut(I::Token) -> bool
{
    Done(input.take_many(condition))
}

#[inline]
pub fn delimited<I: Input, F>(input: &mut I,
                              start: I::Token,
                              mut cond: F,
                              end: I::Token) -> ParseResult<I, I::Many>
    where F: FnMut(I::Token) -> bool
{
    if let Error(mut e) = eat(input, start) {
        e.parser = "delimited";
        return Error(e);
    }

    let output = match take_some_while(input, |c| c != end && cond(c)) {
        Done(output) => output,
        Error(mut e) => {
            e.parser = "delimited";
            return Error(e);
        }
    };

    if let Error(mut e) = eat(input, end) {
        e.parser = "delimited";
        return Error(e);
    }

    Done(output)
}

#[inline(always)]
pub fn eof<I: Input>(input: &mut I) -> ParseResult<I, ()> {
    if input.is_empty() {
        Done(())
    } else {
        error("eof", Expected::EOF)
    }
}