use std::marker::PhantomData;
use super::*;
pub trait Mode {
type ParseResult;
type ExtensionResult;
fn map_err(
result: Self::ParseResult,
f: impl FnOnce(E0) -> E1,
) -> Self::ParseResult;
fn bind(
result: Self::ParseResult,
f: impl FnOnce(A0) -> Result,
) -> Self::ParseResult;
fn seal(result: Self::ParseResult) -> Result;
fn xmap_err(
result: Self::ExtensionResult,
f: impl FnOnce(E0) -> E1,
) -> Self::ExtensionResult;
fn xbind(
result: Self::ExtensionResult,
f: impl FnOnce(A0) -> Result,
) -> Self::ExtensionResult;
}
pub trait ParseMode {
type Mode: ?Sized + Mode;
}
pub trait WithParseMode: ParseMode {
type WithMode: ?Sized;
}
impl WithParseMode for T {
type WithMode = WithMode::Mode>;
}
pub struct WithMode(PhantomData, 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> {
>::pdeserialize(self, inctx)
}
fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> {
>::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 type ParseResultM<'a, Ctx, F, I> =
<::Mode as Mode>::ParseResult, ParseError<'a, Ctx, F>, I>;
pub type ExtensionResultM<'a, Ctx, F> =
<::Mode as Mode>::ExtensionResult, ParseError<'a, Ctx, F>>;
pub trait FactoryModeParse<'a, Ctx: Context<'a>>: FactoryBase<'a, Ctx> + ParseMode {
fn mdeserialize>(&self, inctx: I) -> ParseResultM<'a, Ctx, Self, I>;
fn mextend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ExtensionResultM<'a, Ctx, Self>;
}
pub trait FactoryModeProxy<'a, Ctx: Context<'a>> {
type F: FactoryBase<'a, Ctx> + ParseMode;
fn pmdeserialize>(f: &Self::F, inctx: I)
-> ParseResultM<'a, Ctx, Self::F, I>;
fn pmextend(
f: &Self::F,
mentionable: Mtbl<'a, Ctx, Self::F>,
tail: &[u8],
) -> ExtensionResultM<'a, Ctx, Self::F>;
}
impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx> + WithParseMode> FactoryModeParse<'a, Ctx> for F
where
F::WithMode: FactoryModeProxy<'a, Ctx, F = F>,
{
fn mdeserialize>(&self, inctx: I) -> ParseResultM<'a, Ctx, Self, I> {
>::pmdeserialize(self, inctx)
}
fn mextend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ExtensionResultM<'a, Ctx, Self> {
>::pmextend(self, mentionable, tail)
}
}
pub struct RegularMode;
impl Mode for RegularMode {
type ParseResult = Result;
type ExtensionResult = Result;
fn map_err(
result: Self::ParseResult,
f: impl FnOnce(E0) -> E1,
) -> Self::ParseResult {
result.map_err(f)
}
fn bind(
result: Self::ParseResult,
f: impl FnOnce(A0) -> Result,
) -> Self::ParseResult {
result.and_then(f)
}
fn seal(result: Self::ParseResult) -> Result {
result
}
fn xmap_err(
result: Self::ExtensionResult,
f: impl FnOnce(E0) -> E1,
) -> Self::ExtensionResult {
result.map_err(f)
}
fn xbind(
result: Self::ExtensionResult,
f: impl FnOnce(A0) -> Result,
) -> Self::ExtensionResult {
result.and_then(f)
}
}
pub trait RegularFactory<'a, Ctx: Context<'a>>:
FactoryBase<'a, Ctx> + ParseMode
{
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
{
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)
}
}