use lib::marker::PhantomData;
use error::{ConsumedResult, Info, ParseError, StreamError, Tracked};
use stream::{uncons, Stream, StreamOnce};
use Parser;
use error::FastResult::*;
#[doc(inline)]
pub use self::token as item;
#[derive(Copy, Clone)]
pub struct Any<I>(PhantomData<fn(I) -> I>);
impl<I> Parser for Any<I>
where
I: Stream,
{
type Input = I;
type Output = I::Item;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Self::Input) -> ConsumedResult<I::Item, I> {
uncons(input)
}
}
#[inline(always)]
pub fn any<I>() -> Any<I>
where
I: Stream,
{
Any(PhantomData)
}
#[derive(Copy, Clone)]
pub struct Satisfy<I, P> {
predicate: P,
_marker: PhantomData<I>,
}
fn satisfy_impl<I, P, R>(input: &mut I, mut predicate: P) -> ConsumedResult<R, I>
where
I: Stream,
P: FnMut(I::Item) -> Option<R>,
{
let position = input.position();
match uncons(input) {
EmptyOk(c) | ConsumedOk(c) => match predicate(c.clone()) {
Some(c) => ConsumedOk(c),
None => EmptyErr(I::Error::empty(position).into()),
},
EmptyErr(err) => EmptyErr(err),
ConsumedErr(err) => ConsumedErr(err),
}
}
impl<I, P> Parser for Satisfy<I, P>
where
I: Stream,
P: FnMut(I::Item) -> bool,
{
type Input = I;
type Output = I::Item;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Self::Input) -> ConsumedResult<Self::Output, Self::Input> {
satisfy_impl(input, |c| {
if (self.predicate)(c.clone()) {
Some(c)
} else {
None
}
})
}
}
#[inline(always)]
pub fn satisfy<I, P>(predicate: P) -> Satisfy<I, P>
where
I: Stream,
P: FnMut(I::Item) -> bool,
{
Satisfy {
predicate: predicate,
_marker: PhantomData,
}
}
#[derive(Copy, Clone)]
pub struct SatisfyMap<I, P> {
predicate: P,
_marker: PhantomData<I>,
}
impl<I, P, R> Parser for SatisfyMap<I, P>
where
I: Stream,
P: FnMut(I::Item) -> Option<R>,
{
type Input = I;
type Output = R;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Self::Input) -> ConsumedResult<Self::Output, Self::Input> {
satisfy_impl(input, &mut self.predicate)
}
}
#[inline(always)]
pub fn satisfy_map<I, P, R>(predicate: P) -> SatisfyMap<I, P>
where
I: Stream,
P: FnMut(I::Item) -> Option<R>,
{
SatisfyMap {
predicate: predicate,
_marker: PhantomData,
}
}
#[derive(Copy, Clone)]
pub struct Token<I>
where
I: Stream,
I::Item: PartialEq,
{
c: I::Item,
_marker: PhantomData<I>,
}
impl<I> Parser for Token<I>
where
I: Stream,
I::Item: PartialEq + Clone,
{
type Input = I;
type Output = I::Item;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Self::Input) -> ConsumedResult<I::Item, I> {
satisfy_impl(input, |c| if c == self.c { Some(c) } else { None })
}
fn add_error(&mut self, errors: &mut Tracked<<Self::Input as StreamOnce>::Error>) {
errors.error.add_expected(Info::Token(self.c.clone()));
}
}
#[inline(always)]
pub fn token<I>(c: I::Item) -> Token<I>
where
I: Stream,
I::Item: PartialEq,
{
Token {
c: c,
_marker: PhantomData,
}
}
#[derive(Clone)]
pub struct Tokens<C, T, I>
where
I: Stream,
{
cmp: C,
expected: Info<I::Item, I::Range>,
tokens: T,
_marker: PhantomData<I>,
}
impl<C, T, I> Parser for Tokens<C, T, I>
where
C: FnMut(T::Item, I::Item) -> bool,
T: Clone + IntoIterator,
I: Stream,
{
type Input = I;
type Output = T;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Self::Input) -> ConsumedResult<T, I> {
let start = input.position();
let mut consumed = false;
for c in self.tokens.clone() {
match ::stream::uncons(input) {
ConsumedOk(other) | EmptyOk(other) => {
if !(self.cmp)(c, other.clone()) {
return if consumed {
let mut errors = <Self::Input as StreamOnce>::Error::from_error(
start,
StreamError::unexpected(Info::Token(other)),
);
errors.add_expected(self.expected.clone());
ConsumedErr(errors)
} else {
EmptyErr(<Self::Input as StreamOnce>::Error::empty(start).into())
};
}
consumed = true;
}
EmptyErr(mut error) => {
error.error.set_position(start);
return if consumed {
ConsumedErr(error.error)
} else {
EmptyErr(error.into())
};
}
ConsumedErr(mut error) => {
error.set_position(start);
return ConsumedErr(error);
}
}
}
if consumed {
ConsumedOk(self.tokens.clone())
} else {
EmptyOk(self.tokens.clone())
}
}
fn add_error(&mut self, errors: &mut Tracked<<Self::Input as StreamOnce>::Error>) {
errors.error.add_expected(self.expected.clone());
}
}
#[inline(always)]
pub fn tokens<C, T, I>(cmp: C, expected: Info<I::Item, I::Range>, tokens: T) -> Tokens<C, T, I>
where
C: FnMut(T::Item, I::Item) -> bool,
T: Clone + IntoIterator,
I: Stream,
{
Tokens {
cmp: cmp,
expected: expected,
tokens: tokens,
_marker: PhantomData,
}
}
#[derive(Clone)]
pub struct Tokens2<C, T, I>
where
I: Stream,
{
cmp: C,
tokens: T,
_marker: PhantomData<I>,
}
impl<C, T, I> Parser for Tokens2<C, T, I>
where
C: FnMut(T::Item, I::Item) -> bool,
T: Clone + IntoIterator,
I: Stream,
{
type Input = I;
type Output = T;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Self::Input) -> ConsumedResult<T, I> {
let start = input.position();
let mut consumed = false;
for c in self.tokens.clone() {
match ::stream::uncons(input) {
ConsumedOk(other) | EmptyOk(other) => {
if !(self.cmp)(c, other.clone()) {
return if consumed {
let errors = <Self::Input as StreamOnce>::Error::from_error(
start,
StreamError::unexpected(Info::Token(other)),
);
ConsumedErr(errors)
} else {
EmptyErr(<Self::Input as StreamOnce>::Error::empty(start).into())
};
}
consumed = true;
}
EmptyErr(mut error) => {
error.error.set_position(start);
return if consumed {
ConsumedErr(error.error)
} else {
EmptyErr(error)
};
}
ConsumedErr(mut error) => {
error.set_position(start);
return ConsumedErr(error);
}
}
}
if consumed {
ConsumedOk(self.tokens.clone())
} else {
EmptyOk(self.tokens.clone())
}
}
}
#[inline(always)]
pub fn tokens2<C, T, I>(cmp: C, tokens: T) -> Tokens2<C, T, I>
where
C: FnMut(T::Item, I::Item) -> bool,
T: Clone + IntoIterator,
I: Stream,
{
Tokens2 {
cmp: cmp,
tokens: tokens,
_marker: PhantomData,
}
}
#[derive(Copy, Clone)]
pub struct Position<I>
where
I: Stream,
{
_marker: PhantomData<I>,
}
impl<I> Parser for Position<I>
where
I: Stream,
{
type Input = I;
type Output = I::Position;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Self::Input) -> ConsumedResult<I::Position, I> {
EmptyOk(input.position())
}
}
#[inline(always)]
pub fn position<I>() -> Position<I>
where
I: Stream,
{
Position {
_marker: PhantomData,
}
}
#[derive(Copy, Clone)]
pub struct OneOf<T, I>
where
I: Stream,
{
tokens: T,
_marker: PhantomData<I>,
}
impl<T, I> Parser for OneOf<T, I>
where
T: Clone + IntoIterator<Item = I::Item>,
I: Stream,
I::Item: PartialEq,
{
type Input = I;
type Output = I::Item;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Self::Input) -> ConsumedResult<I::Item, I> {
satisfy(|c| self.tokens.clone().into_iter().any(|t| t == c)).parse_lazy(input)
}
fn add_error(&mut self, errors: &mut Tracked<<Self::Input as StreamOnce>::Error>) {
for expected in self.tokens.clone() {
errors.error.add_expected(Info::Token(expected));
}
}
}
#[inline(always)]
pub fn one_of<T, I>(tokens: T) -> OneOf<T, I>
where
T: Clone + IntoIterator,
I: Stream,
I::Item: PartialEq<T::Item>,
{
OneOf {
tokens: tokens,
_marker: PhantomData,
}
}
#[derive(Copy, Clone)]
pub struct NoneOf<T, I>
where
I: Stream,
{
tokens: T,
_marker: PhantomData<I>,
}
impl<T, I> Parser for NoneOf<T, I>
where
T: Clone + IntoIterator<Item = I::Item>,
I: Stream,
I::Item: PartialEq,
{
type Input = I;
type Output = I::Item;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Self::Input) -> ConsumedResult<I::Item, I> {
satisfy(|c| self.tokens.clone().into_iter().all(|t| t != c)).parse_lazy(input)
}
}
#[inline(always)]
pub fn none_of<T, I>(tokens: T) -> NoneOf<T, I>
where
T: Clone + IntoIterator,
I: Stream,
I::Item: PartialEq<T::Item>,
{
NoneOf {
tokens: tokens,
_marker: PhantomData,
}
}
#[derive(Copy, Clone)]
pub struct Value<I, T>(T, PhantomData<fn(I) -> I>);
impl<I, T> Parser for Value<I, T>
where
I: Stream,
T: Clone,
{
type Input = I;
type Output = T;
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, _: &mut Self::Input) -> ConsumedResult<T, I> {
EmptyOk(self.0.clone())
}
}
#[inline(always)]
pub fn value<I, T>(v: T) -> Value<I, T>
where
I: Stream,
T: Clone,
{
Value(v, PhantomData)
}
#[derive(Copy, Clone)]
pub struct Eof<I>(PhantomData<I>);
impl<I> Parser for Eof<I>
where
I: Stream,
{
type Input = I;
type Output = ();
type PartialState = ();
#[inline]
fn parse_lazy(&mut self, input: &mut Self::Input) -> ConsumedResult<(), I> {
let before = input.checkpoint();
match input.uncons() {
Err(ref err) if *err == StreamError::end_of_input() => EmptyOk(()),
_ => {
input.reset(before);
EmptyErr(<Self::Input as StreamOnce>::Error::empty(input.position()).into())
}
}
}
fn add_error(&mut self, errors: &mut Tracked<<Self::Input as StreamOnce>::Error>) {
errors.error.add_expected("end of input".into());
}
}
#[inline(always)]
pub fn eof<I>() -> Eof<I>
where
I: Stream,
{
Eof(PhantomData)
}