radn-rs/src/rcore/modes.rs
2023-07-29 18:53:13 +00:00

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)
}
}