142 lines
3.8 KiB
Rust
142 lines
3.8 KiB
Rust
use std::marker::PhantomData;
|
|
|
|
use super::*;
|
|
|
|
pub trait Mode {
|
|
type ParseResult<A, E, I>;
|
|
|
|
type ExtensionResult<A, E>;
|
|
|
|
fn map_err<A, E0, E1, I>(
|
|
result: Self::ParseResult<A, E0, I>,
|
|
f: impl FnOnce(E0) -> E1,
|
|
) -> Self::ParseResult<A, E1, I>;
|
|
|
|
fn bind<A0, A1, E, I>(
|
|
result: Self::ParseResult<A0, E, I>,
|
|
f: impl FnOnce(A0) -> Result<A1, E>,
|
|
) -> Self::ParseResult<A1, E, I>;
|
|
|
|
fn seal<A, E, I>(result: Self::ParseResult<A, E, I>) -> Result<A, E>;
|
|
|
|
fn xmap_err<A, E0, E1>(
|
|
result: Self::ExtensionResult<A, E0>,
|
|
f: impl FnOnce(E0) -> E1,
|
|
) -> Self::ExtensionResult<A, E1>;
|
|
|
|
fn xbind<A0, A1, E>(
|
|
result: Self::ExtensionResult<A0, E>,
|
|
f: impl FnOnce(A0) -> Result<A1, E>,
|
|
) -> Self::ExtensionResult<A1, E>;
|
|
}
|
|
|
|
pub trait ParseMode {
|
|
type Mode: ?Sized + Mode;
|
|
}
|
|
|
|
pub trait WithParseMode: ParseMode {
|
|
type WithMode: ?Sized;
|
|
}
|
|
|
|
impl<T: ?Sized + ParseMode> WithParseMode for T {
|
|
type WithMode = WithMode<Self, <Self as ParseMode>::Mode>;
|
|
}
|
|
|
|
pub struct WithMode<T: ?Sized, M: ?Sized>(PhantomData<M>, T);
|
|
|
|
pub trait FactoryProxy<'a, Ctx: Context<'a>> {
|
|
type F: FactoryBase<'a, Ctx> + ParseMode;
|
|
|
|
fn pdeserialize(f: &Self::F, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self::F>;
|
|
fn pextend(
|
|
f: &Self::F,
|
|
mentionable: Mtbl<'a, Ctx, Self::F>,
|
|
tail: &[u8],
|
|
) -> ParseResult<'a, Ctx, Self::F>;
|
|
}
|
|
|
|
impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx> + WithParseMode> FactoryParse<'a, Ctx> for F
|
|
where
|
|
F::WithMode: FactoryProxy<'a, Ctx, F = Self>,
|
|
{
|
|
fn deserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self> {
|
|
<F::WithMode as FactoryProxy<'a, Ctx>>::pdeserialize(self, inctx)
|
|
}
|
|
|
|
fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> {
|
|
<F::WithMode as FactoryProxy<'a, Ctx>>::pextend(self, mentionable, tail)
|
|
}
|
|
}
|
|
|
|
impl<'a, Ctx: Context<'a>, F: FactoryParse<'a, Ctx> + WithParseMode> Factory<'a, Ctx> for F
|
|
where
|
|
F::Mtbl: MentionableTop<'a, Ctx>,
|
|
{
|
|
type _Mtbl = Self::Mtbl;
|
|
}
|
|
|
|
pub struct RegularMode;
|
|
|
|
impl Mode for RegularMode {
|
|
type ParseResult<A, E, I> = Result<A, E>;
|
|
|
|
type ExtensionResult<A, E> = Result<A, E>;
|
|
|
|
fn map_err<A, E0, E1, I>(
|
|
result: Self::ParseResult<A, E0, I>,
|
|
f: impl FnOnce(E0) -> E1,
|
|
) -> Self::ParseResult<A, E1, I> {
|
|
result.map_err(f)
|
|
}
|
|
|
|
fn bind<A0, A1, E, I>(
|
|
result: Self::ParseResult<A0, E, I>,
|
|
f: impl FnOnce(A0) -> Result<A1, E>,
|
|
) -> Self::ParseResult<A1, E, I> {
|
|
result.and_then(f)
|
|
}
|
|
|
|
fn seal<A, E, I>(result: Self::ParseResult<A, E, I>) -> Result<A, E> {
|
|
result
|
|
}
|
|
|
|
fn xmap_err<A, E0, E1>(
|
|
result: Self::ExtensionResult<A, E0>,
|
|
f: impl FnOnce(E0) -> E1,
|
|
) -> Self::ExtensionResult<A, E1> {
|
|
result.map_err(f)
|
|
}
|
|
|
|
fn xbind<A0, A1, E>(
|
|
result: Self::ExtensionResult<A0, E>,
|
|
f: impl FnOnce(A0) -> Result<A1, E>,
|
|
) -> Self::ExtensionResult<A1, E> {
|
|
result.and_then(f)
|
|
}
|
|
}
|
|
|
|
pub trait RegularFactory<'a, Ctx: Context<'a>>:
|
|
FactoryBase<'a, Ctx> + ParseMode<Mode = RegularMode>
|
|
{
|
|
fn rdeserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self>;
|
|
fn rextend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self>;
|
|
}
|
|
|
|
impl<'a, Ctx: Context<'a>, F: RegularFactory<'a, Ctx>> FactoryProxy<'a, Ctx>
|
|
for WithMode<F, RegularMode>
|
|
{
|
|
type F = F;
|
|
|
|
fn pdeserialize(f: &Self::F, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self::F> {
|
|
f.rdeserialize(inctx)
|
|
}
|
|
|
|
fn pextend(
|
|
f: &Self::F,
|
|
mentionable: Mtbl<'a, Ctx, Self::F>,
|
|
tail: &[u8],
|
|
) -> ParseResult<'a, Ctx, Self::F> {
|
|
f.rextend(mentionable, tail)
|
|
}
|
|
}
|