ModeResult

This commit is contained in:
AF 2023-07-29 23:39:09 +00:00
parent e9d0eaf7b1
commit 936f41735a
7 changed files with 160 additions and 138 deletions

View File

@ -34,7 +34,8 @@ pub use self::inctx::InCtx;
pub use self::inlining::{Inlining, InliningExt, InliningResultExt}; pub use self::inlining::{Inlining, InliningExt, InliningResultExt};
pub use self::modes::{ pub use self::modes::{
ExtensionResultM, ExtensionSourceM, FactoryModeParse, FactoryModeProxy, ImplMode, Mode, ExtensionResultM, ExtensionSourceM, FactoryModeParse, FactoryModeProxy, ImplMode, Mode,
ParseMode, ParseResultM, QRegularFactory, RegularFactory, RegularMode, WithMode, WithParseMode, ModeResult, ParseMode, ParseModeExt, ParseResultM, QRegularFactory, RegularFactory,
RegularMode, WithMode, WithParseMode,
}; };
pub use self::origin::{OFctr, Origin}; pub use self::origin::{OFctr, Origin};
pub use self::point::Point; pub use self::point::Point;

View File

@ -2,24 +2,26 @@ use std::marker::PhantomData;
use super::*; use super::*;
pub type ModeResult<M, A, E, I> = Result<<M as Mode>::ParseSuccess<A, I>, E>;
pub trait Mode { pub trait Mode {
type ParseResult<A, E, I>; type ParseSuccess<A, I>;
type ExtensionResult<A, E>; type ExtensionResult<A, E>;
type ExtensionSource<A, E>; type ExtensionSource<A>;
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>( fn bind<A0, A1, E, I>(
result: Self::ParseResult<A0, E, I>, s: Self::ParseSuccess<A0, I>,
f: impl FnOnce(A0) -> Result<A1, E>, f: impl FnOnce(A0) -> Result<A1, E>,
) -> Self::ParseResult<A1, E, I>; ) -> ModeResult<Self, A1, E, I>;
fn seal<A, E, I>(result: Self::ParseResult<A, E, I>) -> Result<A, E>; fn map<A0, A1, I>(
s: Self::ParseSuccess<A0, I>,
f: impl FnOnce(A0) -> A1,
) -> Self::ParseSuccess<A1, I>;
fn seal<A, I>(s: Self::ParseSuccess<A, I>) -> A;
fn xmap_err<A, E0, E1>( fn xmap_err<A, E0, E1>(
result: Self::ExtensionResult<A, E0>, result: Self::ExtensionResult<A, E0>,
@ -33,16 +35,50 @@ pub trait Mode {
fn xseal<A, E>(result: Self::ExtensionResult<A, E>) -> Result<A, E>; fn xseal<A, E>(result: Self::ExtensionResult<A, E>) -> Result<A, E>;
fn smap<A0, A1, E>( fn smap<A0, A1>(
source: Self::ExtensionSource<A0, E>, source: Self::ExtensionSource<A0>,
f: impl FnOnce(A0) -> A1, f: impl FnOnce(A0) -> A1,
) -> Self::ExtensionSource<A1, E>; ) -> Self::ExtensionSource<A1>;
fn prepare<A>(a: A) -> Self::ExtensionSource<A>;
fn xsbind<AB, A, B, E>(
ab: Self::ExtensionSource<AB>,
t2ab: impl FnOnce(AB) -> (A, B),
ce: impl FnOnce(Self::ExtensionSource<B>) -> Self::ExtensionResult<B, E>,
ab2t: impl FnOnce(A, B) -> Result<AB, E>,
) -> Self::ExtensionResult<AB, E>;
} }
pub trait ParseMode { pub trait ParseMode {
type Mode: ?Sized + Mode; type Mode: ?Sized + Mode;
} }
pub trait ParseModeExt: ParseMode {
fn bind<A0, A1, E, I>(
s: <Self::Mode as Mode>::ParseSuccess<A0, I>,
f: impl FnOnce(A0) -> Result<A1, E>,
) -> ModeResult<Self::Mode, A1, E, I> {
<Self::Mode as Mode>::bind(s, f)
}
fn map<A0, A1, I>(
s: <Self::Mode as Mode>::ParseSuccess<A0, I>,
f: impl FnOnce(A0) -> A1,
) -> <Self::Mode as Mode>::ParseSuccess<A1, I> {
<Self::Mode as Mode>::map(s, f)
}
fn smap<A0, A1>(
source: <Self::Mode as Mode>::ExtensionSource<A0>,
f: impl FnOnce(A0) -> A1,
) -> <Self::Mode as Mode>::ExtensionSource<A1> {
<Self::Mode as Mode>::smap(source, f)
}
}
impl<F: ParseMode> ParseModeExt for F {}
pub trait WithParseMode: ParseMode { pub trait WithParseMode: ParseMode {
type WithMode: ?Sized; type WithMode: ?Sized;
} }
@ -63,11 +99,15 @@ pub struct WithMode<T: ?Sized, M: ?Sized>(PhantomData<M>, T);
impl<'a, Ctx: Context<'a>, F: FactoryModeParse<'a, Ctx>> FactoryParse<'a, Ctx> for F { impl<'a, Ctx: Context<'a>, F: FactoryModeParse<'a, Ctx>> FactoryParse<'a, Ctx> for F {
fn deserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self> { fn deserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self> {
<<Self as ParseMode>::Mode as Mode>::seal(self.mdeserialize(inctx)) self.mdeserialize(inctx)
.map(<<Self as ParseMode>::Mode as Mode>::seal)
} }
fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> { fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> {
<<Self as ParseMode>::Mode as Mode>::xseal(self.mextend(Self::mprepare(mentionable), tail)) <<Self as ParseMode>::Mode as Mode>::xseal(self.mextend(
<<Self as ParseMode>::Mode as Mode>::prepare(mentionable),
tail,
))
} }
} }
@ -79,13 +119,13 @@ where
} }
pub type ParseResultM<'a, Ctx, F, I> = pub type ParseResultM<'a, Ctx, F, I> =
<<F as ParseMode>::Mode as Mode>::ParseResult<Mtbl<'a, Ctx, F>, ParseError<'a, Ctx, F>, I>; ModeResult<<F as ParseMode>::Mode, Mtbl<'a, Ctx, F>, ParseError<'a, Ctx, F>, I>;
pub type ExtensionResultM<'a, Ctx, F> = pub type ExtensionResultM<'a, Ctx, F> =
<<F as ParseMode>::Mode as Mode>::ExtensionResult<Mtbl<'a, Ctx, F>, ParseError<'a, Ctx, F>>; <<F as ParseMode>::Mode as Mode>::ExtensionResult<Mtbl<'a, Ctx, F>, ParseError<'a, Ctx, F>>;
pub type ExtensionSourceM<'a, Ctx, F> = pub type ExtensionSourceM<'a, Ctx, F> =
<<F as ParseMode>::Mode as Mode>::ExtensionSource<Mtbl<'a, Ctx, F>, ParseError<'a, Ctx, F>>; <<F as ParseMode>::Mode as Mode>::ExtensionSource<Mtbl<'a, Ctx, F>>;
pub trait FactoryModeParse<'a, Ctx: Context<'a>>: FactoryBase<'a, Ctx> + ParseMode { pub trait FactoryModeParse<'a, Ctx: Context<'a>>: FactoryBase<'a, Ctx> + ParseMode {
fn mdeserialize<I: InCtx<'a, Ctx>>(&self, inctx: I) -> ParseResultM<'a, Ctx, Self, I>; fn mdeserialize<I: InCtx<'a, Ctx>>(&self, inctx: I) -> ParseResultM<'a, Ctx, Self, I>;
@ -95,8 +135,6 @@ pub trait FactoryModeParse<'a, Ctx: Context<'a>>: FactoryBase<'a, Ctx> + ParseMo
mentionable: ExtensionSourceM<'a, Ctx, Self>, mentionable: ExtensionSourceM<'a, Ctx, Self>,
tail: &[u8], tail: &[u8],
) -> ExtensionResultM<'a, Ctx, Self>; ) -> ExtensionResultM<'a, Ctx, Self>;
fn mprepare(mentionable: Self::Mtbl) -> ExtensionSourceM<'a, Ctx, Self>;
} }
pub trait FactoryModeProxy<'a, Ctx: Context<'a>> { pub trait FactoryModeProxy<'a, Ctx: Context<'a>> {
@ -110,8 +148,6 @@ pub trait FactoryModeProxy<'a, Ctx: Context<'a>> {
mentionable: ExtensionSourceM<'a, Ctx, Self::F>, mentionable: ExtensionSourceM<'a, Ctx, Self::F>,
tail: &[u8], tail: &[u8],
) -> ExtensionResultM<'a, Ctx, Self::F>; ) -> ExtensionResultM<'a, Ctx, Self::F>;
fn pmprepare(mentionable: Mtbl<'a, Ctx, Self::F>) -> ExtensionSourceM<'a, Ctx, Self::F>;
} }
impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx> + WithParseMode> FactoryModeParse<'a, Ctx> for F impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx> + WithParseMode> FactoryModeParse<'a, Ctx> for F
@ -129,37 +165,33 @@ where
) -> ExtensionResultM<'a, Ctx, Self> { ) -> ExtensionResultM<'a, Ctx, Self> {
<F::WithMode as FactoryModeProxy<'a, Ctx>>::pmextend(self, mentionable, tail) <F::WithMode as FactoryModeProxy<'a, Ctx>>::pmextend(self, mentionable, tail)
} }
fn mprepare(mentionable: Self::Mtbl) -> ExtensionSourceM<'a, Ctx, Self> {
<F::WithMode as FactoryModeProxy<'a, Ctx>>::pmprepare(mentionable)
}
} }
pub struct RegularMode; pub struct RegularMode;
impl Mode for RegularMode { impl Mode for RegularMode {
type ParseResult<A, E, I> = Result<A, E>; type ParseSuccess<A, I> = A;
type ExtensionResult<A, E> = Result<A, E>; type ExtensionResult<A, E> = Result<A, E>;
type ExtensionSource<A, E> = A; type ExtensionSource<A> = A;
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>( fn bind<A0, A1, E, I>(
result: Self::ParseResult<A0, E, I>, s: Self::ParseSuccess<A0, I>,
f: impl FnOnce(A0) -> Result<A1, E>, f: impl FnOnce(A0) -> Result<A1, E>,
) -> Self::ParseResult<A1, E, I> { ) -> ModeResult<Self, A1, E, I> {
result.and_then(f) f(s)
} }
fn seal<A, E, I>(result: Self::ParseResult<A, E, I>) -> Result<A, E> { fn map<A0, A1, I>(
result s: Self::ParseSuccess<A0, I>,
f: impl FnOnce(A0) -> A1,
) -> Self::ParseSuccess<A1, I> {
f(s)
}
fn seal<A, I>(s: Self::ParseSuccess<A, I>) -> A {
s
} }
fn xmap_err<A, E0, E1>( fn xmap_err<A, E0, E1>(
@ -180,12 +212,26 @@ impl Mode for RegularMode {
result result
} }
fn smap<A0, A1, E>( fn smap<A0, A1>(
source: Self::ExtensionSource<A0, E>, source: Self::ExtensionSource<A0>,
f: impl FnOnce(A0) -> A1, f: impl FnOnce(A0) -> A1,
) -> Self::ExtensionSource<A1, E> { ) -> Self::ExtensionSource<A1> {
f(source) f(source)
} }
fn prepare<A>(a: A) -> Self::ExtensionSource<A> {
a
}
fn xsbind<AB, A, B, E>(
ab: Self::ExtensionSource<AB>,
t2ab: impl FnOnce(AB) -> (A, B),
ce: impl FnOnce(Self::ExtensionSource<B>) -> Self::ExtensionResult<B, E>,
ab2t: impl FnOnce(A, B) -> Result<AB, E>,
) -> Self::ExtensionResult<AB, E> {
let (b, c) = t2ab(ab);
ab2t(b, ce(c)?)
}
} }
pub trait QRegularFactory<'a, Ctx: Context<'a>>: pub trait QRegularFactory<'a, Ctx: Context<'a>>:
@ -226,8 +272,4 @@ impl<'a, Ctx: Context<'a>, F: QRegularFactory<'a, Ctx>> FactoryModeProxy<'a, Ctx
fn pmextend(f: &F, mentionable: Mtbl<'a, Ctx, F>, tail: &[u8]) -> ExtensionResultM<'a, Ctx, F> { fn pmextend(f: &F, mentionable: Mtbl<'a, Ctx, F>, tail: &[u8]) -> ExtensionResultM<'a, Ctx, F> {
f.qrextend(mentionable, tail) f.qrextend(mentionable, tail)
} }
fn pmprepare(mentionable: Mtbl<'a, Ctx, Self::F>) -> ExtensionSourceM<'a, Ctx, Self::F> {
mentionable
}
} }

View File

@ -81,7 +81,7 @@ impl<A: ParseMode> ParseMode for AtomicFactory<A> {
impl<'a, Ctx: Context<'a>, A: AtomicModeParse> FactoryModeParse<'a, Ctx> for AtomicFactory<A> { impl<'a, Ctx: Context<'a>, A: AtomicModeParse> FactoryModeParse<'a, Ctx> for AtomicFactory<A> {
fn mdeserialize<I: InCtx<'a, Ctx>>(&self, inctx: I) -> ParseResultM<'a, Ctx, Self, I> { fn mdeserialize<I: InCtx<'a, Ctx>>(&self, inctx: I) -> ParseResultM<'a, Ctx, Self, I> {
<<A as ParseMode>::Mode as Mode>::bind(A::ma_deserialize(inctx), |a| Ok(a.into())) <<A as ParseMode>::Mode as Mode>::bind(A::ma_deserialize(inctx)?, |a| Ok(a.into()))
} }
fn mextend( fn mextend(
@ -97,10 +97,6 @@ impl<'a, Ctx: Context<'a>, A: AtomicModeParse> FactoryModeParse<'a, Ctx> for Ato
|a| Ok(a.into()), |a| Ok(a.into()),
) )
} }
fn mprepare(mentionable: Self::Mtbl) -> ExtensionSourceM<'a, Ctx, Self> {
<<A as ParseMode>::Mode as Mode>::smap(mentionable.atomic.ma_prepare(), |a| a.into())
}
} }
/// Extension trait to provide method-like utilities associated with [AtomicObject]s. /// Extension trait to provide method-like utilities associated with [AtomicObject]s.

View File

@ -2,28 +2,25 @@ use super::*;
impl<A: AtomicModeParse> Atomic for A { impl<A: AtomicModeParse> Atomic for A {
fn a_deserialize(inlining: impl Inlining) -> AParseResult<Self> { fn a_deserialize(inlining: impl Inlining) -> AParseResult<Self> {
<A::Mode as Mode>::seal(Self::ma_deserialize(inlining)) Self::ma_deserialize(inlining).map(<A::Mode as Mode>::seal)
} }
fn a_extend(self, tail: &[u8]) -> AParseResult<Self> { fn a_extend(self, tail: &[u8]) -> AParseResult<Self> {
<A::Mode as Mode>::xseal(Self::ma_extend(self.ma_prepare(), tail)) <A::Mode as Mode>::xseal(Self::ma_extend(<A::Mode as Mode>::prepare(self), tail))
} }
} }
pub type AParseResultM<A, I> = <<A as ParseMode>::Mode as Mode>::ParseResult<A, AParseError<A>, I>; pub type AParseResultM<A, I> = ModeResult<<A as ParseMode>::Mode, A, AParseError<A>, I>;
pub type AExtensionResultM<A> = pub type AExtensionResultM<A> =
<<A as ParseMode>::Mode as Mode>::ExtensionResult<A, AParseError<A>>; <<A as ParseMode>::Mode as Mode>::ExtensionResult<A, AParseError<A>>;
pub type AExtensionSourceM<A> = pub type AExtensionSourceM<A> = <<A as ParseMode>::Mode as Mode>::ExtensionSource<A>;
<<A as ParseMode>::Mode as Mode>::ExtensionSource<A, AParseError<A>>;
pub trait AtomicModeParse: AtomicBase + ParseMode { pub trait AtomicModeParse: AtomicBase + ParseMode {
fn ma_deserialize<I: Inlining>(inlining: I) -> AParseResultM<Self, I>; fn ma_deserialize<I: Inlining>(inlining: I) -> AParseResultM<Self, I>;
fn ma_extend(atomic: AExtensionSourceM<Self>, tail: &[u8]) -> AExtensionResultM<Self>; fn ma_extend(atomic: AExtensionSourceM<Self>, tail: &[u8]) -> AExtensionResultM<Self>;
fn ma_prepare(self) -> AExtensionSourceM<Self>;
} }
pub trait AtomicModeProxy { pub trait AtomicModeProxy {
@ -32,8 +29,6 @@ pub trait AtomicModeProxy {
fn pma_deserialize<I: Inlining>(inlining: I) -> AParseResultM<Self::A, I>; fn pma_deserialize<I: Inlining>(inlining: I) -> AParseResultM<Self::A, I>;
fn pma_extend(atomic: AExtensionSourceM<Self::A>, tail: &[u8]) -> AExtensionResultM<Self::A>; fn pma_extend(atomic: AExtensionSourceM<Self::A>, tail: &[u8]) -> AExtensionResultM<Self::A>;
fn pma_prepare(atomic: Self::A) -> AExtensionSourceM<Self::A>;
} }
impl<A: AtomicBase + WithParseMode> AtomicModeParse for A impl<A: AtomicBase + WithParseMode> AtomicModeParse for A
@ -47,10 +42,6 @@ where
fn ma_extend(atomic: AExtensionSourceM<Self>, tail: &[u8]) -> AExtensionResultM<Self> { fn ma_extend(atomic: AExtensionSourceM<Self>, tail: &[u8]) -> AExtensionResultM<Self> {
<<A as WithParseMode>::WithMode as AtomicModeProxy>::pma_extend(atomic, tail) <<A as WithParseMode>::WithMode as AtomicModeProxy>::pma_extend(atomic, tail)
} }
fn ma_prepare(self) -> AExtensionSourceM<Self> {
<<A as WithParseMode>::WithMode as AtomicModeProxy>::pma_prepare(self)
}
} }
pub trait RegularAtomic: AtomicBase + ParseMode<Mode = RegularMode> { pub trait RegularAtomic: AtomicBase + ParseMode<Mode = RegularMode> {
@ -68,8 +59,4 @@ impl<A: RegularAtomic> AtomicModeProxy for WithMode<A, RegularMode> {
fn pma_extend(atomic: AExtensionSourceM<Self::A>, tail: &[u8]) -> AExtensionResultM<Self::A> { fn pma_extend(atomic: AExtensionSourceM<Self::A>, tail: &[u8]) -> AExtensionResultM<Self::A> {
atomic.ra_extend(tail) atomic.ra_extend(tail)
} }
fn pma_prepare(atomic: Self::A) -> AExtensionSourceM<Self::A> {
atomic
}
} }

View File

@ -60,8 +60,12 @@ where
(&factory_data.0, &factory_data.1) (&factory_data.0, &factory_data.1)
} }
fn from_parsed(_factory_data: &Self::FactoryData, a: Self::A, b: Self::B) -> Self { fn from_parsed(
(a, b) _factory_data: &Self::FactoryData,
a: Self::A,
b: Self::B,
) -> Result<Self, Self::ParseError> {
Ok((a, b))
} }
fn from_error_a( fn from_error_a(

View File

@ -3,30 +3,30 @@ use super::*;
pub struct InliningMode; pub struct InliningMode;
impl Mode for InliningMode { impl Mode for InliningMode {
type ParseResult<A, E, I> = Result<(A, I), E>; type ParseSuccess<A, I> = (A, I);
type ExtensionResult<A, E> = E; type ExtensionResult<A, E> = E;
type ExtensionSource<A, E> = (); type ExtensionSource<A> = ();
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>( fn bind<A0, A1, E, I>(
result: Self::ParseResult<A0, E, I>, s: Self::ParseSuccess<A0, I>,
f: impl FnOnce(A0) -> Result<A1, E>, f: impl FnOnce(A0) -> Result<A1, E>,
) -> Self::ParseResult<A1, E, I> { ) -> ModeResult<Self, A1, E, I> {
let (a0, i) = result?; let (a0, i) = s;
let a1 = f(a0)?; let a1 = f(a0)?;
Ok((a1, i)) Ok((a1, i))
} }
fn seal<A, E, I>(result: Self::ParseResult<A, E, I>) -> Result<A, E> { fn map<A0, A1, I>(
result.map(|(a, _)| a) s: Self::ParseSuccess<A0, I>,
f: impl FnOnce(A0) -> A1,
) -> Self::ParseSuccess<A1, I> {
(f(s.0), s.1)
}
fn seal<A, I>(s: Self::ParseSuccess<A, I>) -> A {
s.0
} }
fn xmap_err<A, E0, E1>( fn xmap_err<A, E0, E1>(
@ -47,12 +47,23 @@ impl Mode for InliningMode {
Err(result) Err(result)
} }
fn smap<A0, A1, E>( fn smap<A0, A1>(
source: Self::ExtensionSource<A0, E>, source: Self::ExtensionSource<A0>,
_f: impl FnOnce(A0) -> A1, _f: impl FnOnce(A0) -> A1,
) -> Self::ExtensionSource<A1, E> { ) -> Self::ExtensionSource<A1> {
source source
} }
fn prepare<A>(_a: A) -> Self::ExtensionSource<A> {}
fn xsbind<AB, A, B, E>(
_ab: Self::ExtensionSource<AB>,
_t2ab: impl FnOnce(AB) -> (A, B),
ce: impl FnOnce(Self::ExtensionSource<B>) -> Self::ExtensionResult<B, E>,
_ab2t: impl FnOnce(A, B) -> Result<AB, E>,
) -> Self::ExtensionResult<AB, E> {
ce(())
}
} }
impl<'a, Ctx: Context<'a>, F: QInliningFactory<'a, Ctx>> FactoryModeProxy<'a, Ctx> impl<'a, Ctx: Context<'a>, F: QInliningFactory<'a, Ctx>> FactoryModeProxy<'a, Ctx>
@ -71,8 +82,6 @@ impl<'a, Ctx: Context<'a>, F: QInliningFactory<'a, Ctx>> FactoryModeProxy<'a, Ct
) -> ExtensionResultM<'a, Ctx, F> { ) -> ExtensionResultM<'a, Ctx, F> {
f.qextension_error(tail) f.qextension_error(tail)
} }
fn pmprepare(_mentionable: Mtbl<'a, Ctx, Self::F>) -> ExtensionSourceM<'a, Ctx, Self::F> {}
} }
impl<A: QInliningAtomic> AtomicModeProxy for WithMode<A, InliningMode> { impl<A: QInliningAtomic> AtomicModeProxy for WithMode<A, InliningMode> {
@ -85,6 +94,4 @@ impl<A: QInliningAtomic> AtomicModeProxy for WithMode<A, InliningMode> {
fn pma_extend(_atomic: AExtensionSourceM<Self::A>, tail: &[u8]) -> AExtensionResultM<Self::A> { fn pma_extend(_atomic: AExtensionSourceM<Self::A>, tail: &[u8]) -> AExtensionResultM<Self::A> {
A::qa_extension_error(tail) A::qa_extension_error(tail)
} }
fn pma_prepare(_atomic: Self::A) -> AExtensionSourceM<Self::A> {}
} }

View File

@ -29,7 +29,7 @@ pub trait StaticPairSerializable {
/// ///
/// Note: [`StaticPair::FA`] requires [`InliningFactory`] be implemented. /// Note: [`StaticPair::FA`] requires [`InliningFactory`] be implemented.
pub trait StaticPair<'a, Ctx: Context<'a>>: pub trait StaticPair<'a, Ctx: Context<'a>>:
'a + StaticPairSerializable<SA = Self::A, SB = Self::B> 'a + StaticPairSerializable<SA = Self::A, SB = Self::B> + Sized
{ {
/// [Factory] data. May, depending on the usecase, include factory (factories) on the element(s). /// [Factory] data. May, depending on the usecase, include factory (factories) on the element(s).
type FactoryData: 'a + Send + Sync + Clone; type FactoryData: 'a + Send + Sync + Clone;
@ -47,7 +47,11 @@ pub trait StaticPair<'a, Ctx: Context<'a>>:
/// Borrow both elements' factories. /// Borrow both elements' factories.
fn factories(factory_data: &Self::FactoryData) -> (&Self::FA, &Self::FB); fn factories(factory_data: &Self::FactoryData) -> (&Self::FA, &Self::FB);
/// Construct the object from the elements. /// Construct the object from the elements.
fn from_parsed(factory_data: &Self::FactoryData, a: Self::A, b: Self::B) -> Self; fn from_parsed(
factory_data: &Self::FactoryData,
a: Self::A,
b: Self::B,
) -> Result<Self, Self::ParseError>;
/// Regularise the error returned while parsing the first element. /// Regularise the error returned while parsing the first element.
fn from_error_a( fn from_error_a(
factory_data: &Self::FactoryData, factory_data: &Self::FactoryData,
@ -140,62 +144,43 @@ impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> FactoryBase<'a, Ctx>
type ParseError = SP::ParseError; type ParseError = SP::ParseError;
} }
impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> ImplMode for StaticPairFactory<'a, Ctx, SP> { impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> ParseMode for StaticPairFactory<'a, Ctx, SP> {
type Mode = <SP::FB as ParseMode>::Mode; type Mode = <SP::FB as ParseMode>::Mode;
} }
impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> QRegularFactory<'a, Ctx> impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> FactoryModeParse<'a, Ctx>
for StaticPairFactory<'a, Ctx, SP> for StaticPairFactory<'a, Ctx, SP>
where where
SP::FB: RegularFactory<'a, Ctx>, SP::FB: FactoryModeParse<'a, Ctx>,
{ {
fn qrdeserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self> { fn mdeserialize<I: InCtx<'a, Ctx>>(&self, inctx: I) -> ParseResultM<'a, Ctx, Self, I> {
let (fa, fb) = SP::factories(&self.factory_data); let (fa, fb) = SP::factories(&self.factory_data);
let (a, inctx) = fa let (a, inctx) = fa
.ideserialize(inctx) .ideserialize(inctx)
.map_err(|e| SP::from_error_a(&self.factory_data, e))?; .map_err(|e| SP::from_error_a(&self.factory_data, e))?;
let b = fb Self::bind(
.rdeserialize(inctx) fb.mdeserialize(inctx)
.map_err(|e| SP::from_error_b(&self.factory_data, e))?; .map_err(|e| SP::from_error_b(&self.factory_data, e))?,
Ok(StaticPairObject { |b| SP::from_parsed(&self.factory_data, a, b).map(|pair| StaticPairObject { pair }),
pair: SP::from_parsed(&self.factory_data, a, b), )
}
fn mextend(
&self,
mentionable: ExtensionSourceM<'a, Ctx, Self>,
tail: &[u8],
) -> ExtensionResultM<'a, Ctx, Self> {
let (_, fb) = SP::factories(&self.factory_data);
<Self::Mode as Mode>::xsbind(
mentionable,
|StaticPairObject { pair }| pair.into_elements(),
|b| {
<Self::Mode as Mode>::xmap_err(fb.mextend(b, tail), |e| {
SP::from_error_b(&self.factory_data, e)
}) })
}
fn qrextend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> {
let (_, fb) = SP::factories(&self.factory_data);
let (a, b) = mentionable.pair.into_elements();
match fb.rextend(b, tail) {
Ok(b) => Ok(SP::from_parsed(&self.factory_data, a, b).into()),
Err(e) => Err(SP::from_error_b(&self.factory_data, e)),
}
}
}
impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> QInliningFactory<'a, Ctx>
for StaticPairFactory<'a, Ctx, SP>
where
SP::FB: InliningFactory<'a, Ctx>,
{
fn qextension_error(&self, tail: &[u8]) -> Self::ParseError {
let (_, fb) = SP::factories(&self.factory_data);
SP::from_error_b(&self.factory_data, fb.extension_error(tail))
}
fn qideserialize<I: InCtx<'a, Ctx>>(&self, inctx: I) -> IParseResult<'a, Ctx, Self, I> {
let (fa, fb) = SP::factories(&self.factory_data);
let (a, inctx) = fa
.ideserialize(inctx)
.map_err(|e| SP::from_error_a(&self.factory_data, e))?;
let (b, inctx) = fb
.ideserialize(inctx)
.map_err(|e| SP::from_error_b(&self.factory_data, e))?;
Ok((
StaticPairObject {
pair: SP::from_parsed(&self.factory_data, a, b),
}, },
inctx, |a, b| SP::from_parsed(&self.factory_data, a, b).map(|pair| StaticPairObject { pair }),
)) )
} }
} }
@ -203,7 +188,7 @@ impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> FixedSizeFactory<'a, Ctx>
for StaticPairFactory<'a, Ctx, SP> for StaticPairFactory<'a, Ctx, SP>
where where
SP::FA: FixedSizeFactory<'a, Ctx>, SP::FA: FixedSizeFactory<'a, Ctx>,
SP::FB: FixedSizeFactory<'a, Ctx>, SP::FB: FixedSizeFactory<'a, Ctx> + FactoryModeParse<'a, Ctx>,
{ {
fn size(&self) -> usize { fn size(&self) -> usize {
let (fa, fb) = SP::factories(&self.factory_data); let (fa, fb) = SP::factories(&self.factory_data);
@ -215,7 +200,7 @@ impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> ConstSizeFactory<'a, Ctx>
for StaticPairFactory<'a, Ctx, SP> for StaticPairFactory<'a, Ctx, SP>
where where
SP::FA: ConstSizeFactory<'a, Ctx>, SP::FA: ConstSizeFactory<'a, Ctx>,
SP::FB: ConstSizeFactory<'a, Ctx>, SP::FB: ConstSizeFactory<'a, Ctx> + FactoryModeParse<'a, Ctx>,
{ {
const SIZE: usize = SP::FA::SIZE + SP::FB::SIZE; const SIZE: usize = SP::FA::SIZE + SP::FB::SIZE;
} }