diff --git a/src/rcore.rs b/src/rcore.rs index 2b8a2c3..470af6a 100644 --- a/src/rcore.rs +++ b/src/rcore.rs @@ -7,6 +7,7 @@ mod context; mod dectx; mod demoted; mod diagnostic; +mod factory_modes; mod hashing; mod inctx; mod inlining; @@ -28,6 +29,9 @@ pub use self::context::Context; use self::dectx::{DeCtx, DeCtxT}; pub use self::demoted::Demoted; pub use self::diagnostic::Diagnostic; +pub use self::factory_modes::{ + FactoryProxy, ModeFactory, RegularFactory, RegularFactoryMode, WithMode, +}; pub use self::hashing::{Hash, HASH_SIZE, HASH_ZEROS}; pub use self::inctx::InCtx; pub use self::inlining::{Inlining, InliningExt, InliningResultExt}; diff --git a/src/rcore/factory_modes.rs b/src/rcore/factory_modes.rs new file mode 100644 index 0000000..a4e2e26 --- /dev/null +++ b/src/rcore/factory_modes.rs @@ -0,0 +1,68 @@ +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>; +} + +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) + } +}