wasm-reader-traits 0.1.1

Helper traits for wasm-reader (split to allow using derive macros in the main crate)
Documentation
use crate::{
    iter::{IntoParserIter, ParserIter},
    Parser,
};
use frunk_core::hlist::{HCons, HNil};
use std::{io::Read, marker::PhantomData};

pub struct Iter<F>(pub F);
pub struct Simple<F>(pub F);

pub trait ReaderRead {
    type Out;
    type Error;

    fn read<R: Read>(self, reader: R) -> Result<Self::Out, Self::Error>;
}

pub struct Reader<P, S = (), F = HNil> {
    parsers: P,
    funcs: F,
    state: S,
}

impl<P> Reader<P> {
    #[inline]
    pub fn new(parsers: P) -> Self {
        Reader {
            parsers: parsers,
            funcs: HNil,
            state: (),
        }
    }
}

impl<P, S> Reader<P, S> {
    #[inline]
    pub fn with_state<NS>(self, state: NS) -> Reader<P, NS> {
        Reader {
            parsers: self.parsers,
            funcs: self.funcs,
            state,
        }
    }
}

pub trait ReaderReadHelper {
    type Out;
    type Error;

    fn exec<R: Read>(self, reader: R) -> Result<Self::Out, Self::Error>;
}

impl<S, P, F, Rest> ReaderReadHelper for (P, HCons<Simple<F>, Rest>, S)
where
    P: Parser,
    (P::Next, Rest, S): ReaderReadHelper<Out = S, Error = P::Error>,
    F: FnOnce(&mut S, P::Item) -> Result<(), P::Error>,
{
    type Out = S;
    type Error = P::Error;

    #[inline]
    fn exec<R: Read>(self, mut reader: R) -> Result<S, Self::Error> {
        let (
            p,
            HCons {
                head: Simple(f),
                tail,
            },
            mut state,
        ) = self;
        let (item, next) = p.next(&mut reader)?;
        f(&mut state, item)?;
        Ok((next, tail, state).exec(reader)?)
    }
}

impl<S, P, F> ReaderReadHelper for (P, HCons<Simple<F>, HNil>, S)
where
    P: Parser<Next = ()>,
    F: FnOnce(&mut S, P::Item) -> Result<(), P::Error>,
{
    type Out = S;
    type Error = P::Error;

    #[inline]
    fn exec<R: Read>(self, mut reader: R) -> Result<S, Self::Error> {
        let (
            p,
            HCons {
                head: Simple(f),
                tail: HNil,
            },
            mut state,
        ) = self;
        let (item, ()) = p.next(&mut reader)?;
        f(&mut state, item)?;
        Ok(state)
    }
}

impl<S, I, P, F, Rest> ReaderReadHelper for (P, HCons<Iter<F>, Rest>, S)
where
    P: Parser<Item = Option<I>>,
    I: Parser<Next = Option<I>>,
    (P::Next, Rest, S): ReaderReadHelper<Out = S, Error = P::Error>,
    F: FnOnce(&mut S, ParserIter<&mut dyn Read, Option<I>>) -> Result<(), P::Error>,
{
    type Out = S;
    type Error = P::Error;

    #[inline]
    fn exec<R: Read>(self, mut reader: R) -> Result<S, Self::Error> {
        let (
            p,
            HCons {
                head: Iter(f),
                tail,
            },
            mut state,
        ) = self;
        let (item, next) = p.next(&mut reader)?;
        f(&mut state, item.parse_iter(&mut reader))?;
        Ok((next, tail, state).exec(reader)?)
    }
}

impl<PS, FS, S> ReaderRead for Reader<PS, S, FS>
where
    (PS, FS, S): ReaderReadHelper<Out = S>,
{
    type Out = S;
    type Error = <(PS, FS, S) as ReaderReadHelper>::Error;

    #[inline]
    fn read<R: Read>(self, reader: R) -> Result<S, Self::Error> {
        let Reader {
            parsers,
            funcs,
            state,
        } = self;

        (parsers, funcs, state).exec(reader)
    }
}

pub trait ReaderBuildHelper<S, F> {
    type New;

    fn then(self, func: F) -> Self::New;
}

impl<S, P, F, O> ReaderBuildHelper<S, Simple<F>> for (PhantomData<P>, HNil)
where
    P: Parser,
    F: FnOnce(&mut S, P::Item) -> O,
    O: Into<Result<(), P::Error>>,
{
    type New = HCons<Simple<F>, HNil>;

    #[inline]
    fn then(self, func: Simple<F>) -> Self::New {
        HCons {
            head: func,
            tail: HNil,
        }
    }
}

impl<S, P, I, F, O> ReaderBuildHelper<S, Iter<F>> for (PhantomData<P>, HNil)
where
    P: Parser<Item = Option<I>>,
    I: Parser<Next = Option<I>>,
    F: FnOnce(&mut S, ParserIter<&mut dyn Read, Option<I>>) -> O,
    O: Into<Result<(), P::Error>>,
{
    type New = HCons<Iter<F>, HNil>;

    #[inline]
    fn then(self, func: Iter<F>) -> Self::New {
        HCons {
            head: func,
            tail: HNil,
        }
    }
}

impl<S, P, ExistingF, Rest, F> ReaderBuildHelper<S, F> for (PhantomData<P>, HCons<ExistingF, Rest>)
where
    P: Parser,
    (PhantomData<P::Next>, Rest): ReaderBuildHelper<S, F>,
{
    type New = HCons<ExistingF, <(PhantomData<P::Next>, Rest) as ReaderBuildHelper<S, F>>::New>;

    #[inline]
    fn then(self, func: F) -> Self::New {
        let (_, HCons { head, tail }) = self;
        HCons {
            head,
            tail: (PhantomData, tail).then(func),
        }
    }
}

pub trait ReaderBuild<F> {
    type New;

    fn then(self, func: F) -> Self::New;
}

pub trait ReaderBuildIter<F> {
    type New;

    fn then_iter(self, func: F) -> Self::New;
}

impl<PS, FS, F, S> ReaderBuild<F> for Reader<PS, S, FS>
where
    (PhantomData<PS>, FS): ReaderBuildHelper<S, Simple<F>>,
{
    type New = Reader<PS, S, <(PhantomData<PS>, FS) as ReaderBuildHelper<S, Simple<F>>>::New>;

    #[inline]
    fn then(self, func: F) -> Self::New {
        Reader {
            parsers: self.parsers,
            funcs: (PhantomData, self.funcs).then(Simple(func)),
            state: self.state,
        }
    }
}

impl<PS, FS, F, S> ReaderBuildIter<F> for Reader<PS, S, FS>
where
    (PhantomData<PS>, FS): ReaderBuildHelper<S, Iter<F>>,
{
    type New = Reader<PS, S, <(PhantomData<PS>, FS) as ReaderBuildHelper<S, Iter<F>>>::New>;

    #[inline]
    fn then_iter(self, func: F) -> Self::New {
        Reader {
            parsers: self.parsers,
            funcs: (PhantomData, self.funcs).then(Iter(func)),
            state: self.state,
        }
    }
}