use std::marker::PhantomData; use super::*; pub trait ModeFactory { type Mode: ?Sized; } pub struct RegularFactoryMode; pub trait RegularFactory<'a, Ctx: Context<'a>>: FactoryBase<'a, Ctx> + ModeFactory { fn rdeserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self>; fn rextend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self>; } pub trait FactoryWithMode: ModeFactory { type WithMode: ?Sized; } pub struct WithMode(PhantomData, F); impl FactoryWithMode for F { type WithMode = WithMode::Mode>; } pub trait FactoryProxy<'a, Ctx: Context<'a>> { type F: FactoryBase<'a, Ctx> + ModeFactory; 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: 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) } } impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx> + FactoryWithMode> Factory<'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) } }