use std::{marker::PhantomData, convert::Infallible};
use crate::{Parser, ParserString};
pub struct Chain<T, U, P1, P2>
{
p1: P1,
p2: P2,
t: PhantomData<T>,
u: PhantomData<U>,
}
impl<T, U, P1, P2, E> Chain<T, U, P1, P2>
where
P1: Parser<T>,
E: Into<P1::Err>,
P2: Parser<U, Err = E>,
{
pub fn new(p1: P1, p2: P2) -> Self { Self { p1, p2, t: PhantomData, u: PhantomData } }
}
impl<T, U, P1, P2, E> Parser<(T, U)> for Chain<T, U, P1, P2>
where
P1: Parser<T>,
E: Into<P1::Err>,
P2: Parser<U, Err = E>,
{
type Err = P1::Err;
fn parse(&self, s: &mut ParserString) -> Result<(T, U), Self::Err> {
Ok((
self.p1.parse(s)?,
self.p2.parse(s).map_err(|e| e.into())?
))
}
}
pub struct Or<T, E, P1, P2>
where
P1: Parser<T>,
E: Into<P1::Err>,
P2: Parser<T, Err = E>
{
p1: P1,
p2: P2,
t: PhantomData<T>,
e: PhantomData<E>
}
impl<T, E, P1, P2> Or<T, E, P1, P2>
where
P1: Parser<T>,
E: Into<P1::Err>,
P2: Parser<T, Err = E>
{
pub fn new(p1: P1, p2: P2) -> Self { Self { p1, p2, t: PhantomData, e: PhantomData } }
}
impl<T, E, P1, P2> Parser<T> for Or<T, E, P1, P2>
where
P1: Parser<T>,
E: Into<P1::Err>,
P2: Parser<T, Err = E>
{
type Err = P1::Err;
fn parse(&self, s: &mut ParserString) -> Result<T, Self::Err> {
match self.p1.try_parse(s) {
Ok(v) => Ok(v),
Err(_) => self.p2.parse(s).map_err(Into::into),
}
}
}
pub struct Many<T, P>
where
P: Parser<T>
{
p: P,
t: PhantomData<T>
}
impl<T, P> Many<T, P>
where
P: Parser<T>
{
pub fn new(p: P) -> Self { Self { p, t: PhantomData } }
}
impl<T, P> Parser<Vec<T>> for Many<T, P>
where
P: Parser<T>
{
type Err = Infallible;
fn parse(&self, s: &mut ParserString) -> Result<Vec<T>, Self::Err> {
let mut out = vec![];
while let Ok(v) = self.p.try_parse(s) {
out.push(v)
}
Ok(out)
}
}
pub struct Many1<T, P>
where
P: Parser<T>
{
p: P,
t: PhantomData<T>
}
impl<T, P> Many1<T, P>
where
P: Parser<T>
{
pub fn new(p: P) -> Self { Self { p, t: PhantomData } }
}
impl<T, P> Parser<Vec<T>> for Many1<T, P>
where
P: Parser<T>
{
type Err = P::Err;
fn parse(&self, s: &mut ParserString) -> Result<Vec<T>, Self::Err> {
let mut out = vec![self.p.parse(s)?];
while let Ok(v) = self.p.try_parse(s) {
out.push(v)
}
Ok(out)
}
}