From 936f41735a4f7913e49fb16c44e89901bf703568 Mon Sep 17 00:00:00 2001 From: timofey Date: Sat, 29 Jul 2023 23:39:09 +0000 Subject: [PATCH] `ModeResult` --- src/rcore.rs | 3 +- src/rcore/modes.rs | 134 ++++++++++++++++++++----------- src/rstd/atomic/atomic_object.rs | 6 +- src/rstd/atomic/modes.rs | 21 +---- src/rstd/collections/pair.rs | 8 +- src/rstd/inlining/modes.rs | 49 ++++++----- src/rstd/inlining/static_pair.rs | 77 +++++++----------- 7 files changed, 160 insertions(+), 138 deletions(-) diff --git a/src/rcore.rs b/src/rcore.rs index f928710..b503b3d 100644 --- a/src/rcore.rs +++ b/src/rcore.rs @@ -34,7 +34,8 @@ pub use self::inctx::InCtx; pub use self::inlining::{Inlining, InliningExt, InliningResultExt}; pub use self::modes::{ 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::point::Point; diff --git a/src/rcore/modes.rs b/src/rcore/modes.rs index 3fbfc38..9f7a6af 100644 --- a/src/rcore/modes.rs +++ b/src/rcore/modes.rs @@ -2,24 +2,26 @@ use std::marker::PhantomData; use super::*; +pub type ModeResult = Result<::ParseSuccess, E>; + pub trait Mode { - type ParseResult; + type ParseSuccess; type ExtensionResult; - type ExtensionSource; - - fn map_err( - result: Self::ParseResult, - f: impl FnOnce(E0) -> E1, - ) -> Self::ParseResult; + type ExtensionSource; fn bind( - result: Self::ParseResult, + s: Self::ParseSuccess, f: impl FnOnce(A0) -> Result, - ) -> Self::ParseResult; + ) -> ModeResult; - fn seal(result: Self::ParseResult) -> Result; + fn map( + s: Self::ParseSuccess, + f: impl FnOnce(A0) -> A1, + ) -> Self::ParseSuccess; + + fn seal(s: Self::ParseSuccess) -> A; fn xmap_err( result: Self::ExtensionResult, @@ -33,16 +35,50 @@ pub trait Mode { fn xseal(result: Self::ExtensionResult) -> Result; - fn smap( - source: Self::ExtensionSource, + fn smap( + source: Self::ExtensionSource, f: impl FnOnce(A0) -> A1, - ) -> Self::ExtensionSource; + ) -> Self::ExtensionSource; + + fn prepare(a: A) -> Self::ExtensionSource; + + fn xsbind( + ab: Self::ExtensionSource, + t2ab: impl FnOnce(AB) -> (A, B), + ce: impl FnOnce(Self::ExtensionSource) -> Self::ExtensionResult, + ab2t: impl FnOnce(A, B) -> Result, + ) -> Self::ExtensionResult; } pub trait ParseMode { type Mode: ?Sized + Mode; } +pub trait ParseModeExt: ParseMode { + fn bind( + s: ::ParseSuccess, + f: impl FnOnce(A0) -> Result, + ) -> ModeResult { + ::bind(s, f) + } + + fn map( + s: ::ParseSuccess, + f: impl FnOnce(A0) -> A1, + ) -> ::ParseSuccess { + ::map(s, f) + } + + fn smap( + source: ::ExtensionSource, + f: impl FnOnce(A0) -> A1, + ) -> ::ExtensionSource { + ::smap(source, f) + } +} + +impl ParseModeExt for F {} + pub trait WithParseMode: ParseMode { type WithMode: ?Sized; } @@ -63,11 +99,15 @@ pub struct WithMode(PhantomData, T); 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> { - <::Mode as Mode>::seal(self.mdeserialize(inctx)) + self.mdeserialize(inctx) + .map(<::Mode as Mode>::seal) } fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> { - <::Mode as Mode>::xseal(self.mextend(Self::mprepare(mentionable), tail)) + <::Mode as Mode>::xseal(self.mextend( + <::Mode as Mode>::prepare(mentionable), + tail, + )) } } @@ -79,13 +119,13 @@ where } pub type ParseResultM<'a, Ctx, F, I> = - <::Mode as Mode>::ParseResult, ParseError<'a, Ctx, F>, I>; + ModeResult<::Mode, Mtbl<'a, Ctx, F>, ParseError<'a, Ctx, F>, I>; pub type ExtensionResultM<'a, Ctx, F> = <::Mode as Mode>::ExtensionResult, ParseError<'a, Ctx, F>>; pub type ExtensionSourceM<'a, Ctx, F> = - <::Mode as Mode>::ExtensionSource, ParseError<'a, Ctx, F>>; + <::Mode as Mode>::ExtensionSource>; pub trait FactoryModeParse<'a, Ctx: Context<'a>>: FactoryBase<'a, Ctx> + ParseMode { fn mdeserialize>(&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>, tail: &[u8], ) -> ExtensionResultM<'a, Ctx, Self>; - - fn mprepare(mentionable: Self::Mtbl) -> ExtensionSourceM<'a, Ctx, Self>; } pub trait FactoryModeProxy<'a, Ctx: Context<'a>> { @@ -110,8 +148,6 @@ pub trait FactoryModeProxy<'a, Ctx: Context<'a>> { mentionable: ExtensionSourceM<'a, Ctx, Self::F>, tail: &[u8], ) -> 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 @@ -129,37 +165,33 @@ where ) -> ExtensionResultM<'a, Ctx, Self> { >::pmextend(self, mentionable, tail) } - - fn mprepare(mentionable: Self::Mtbl) -> ExtensionSourceM<'a, Ctx, Self> { - >::pmprepare(mentionable) - } } pub struct RegularMode; impl Mode for RegularMode { - type ParseResult = Result; + type ParseSuccess = A; type ExtensionResult = Result; - type ExtensionSource = A; - - fn map_err( - result: Self::ParseResult, - f: impl FnOnce(E0) -> E1, - ) -> Self::ParseResult { - result.map_err(f) - } + type ExtensionSource = A; fn bind( - result: Self::ParseResult, + s: Self::ParseSuccess, f: impl FnOnce(A0) -> Result, - ) -> Self::ParseResult { - result.and_then(f) + ) -> ModeResult { + f(s) } - fn seal(result: Self::ParseResult) -> Result { - result + fn map( + s: Self::ParseSuccess, + f: impl FnOnce(A0) -> A1, + ) -> Self::ParseSuccess { + f(s) + } + + fn seal(s: Self::ParseSuccess) -> A { + s } fn xmap_err( @@ -180,12 +212,26 @@ impl Mode for RegularMode { result } - fn smap( - source: Self::ExtensionSource, + fn smap( + source: Self::ExtensionSource, f: impl FnOnce(A0) -> A1, - ) -> Self::ExtensionSource { + ) -> Self::ExtensionSource { f(source) } + + fn prepare(a: A) -> Self::ExtensionSource { + a + } + + fn xsbind( + ab: Self::ExtensionSource, + t2ab: impl FnOnce(AB) -> (A, B), + ce: impl FnOnce(Self::ExtensionSource) -> Self::ExtensionResult, + ab2t: impl FnOnce(A, B) -> Result, + ) -> Self::ExtensionResult { + let (b, c) = t2ab(ab); + ab2t(b, ce(c)?) + } } 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> { f.qrextend(mentionable, tail) } - - fn pmprepare(mentionable: Mtbl<'a, Ctx, Self::F>) -> ExtensionSourceM<'a, Ctx, Self::F> { - mentionable - } } diff --git a/src/rstd/atomic/atomic_object.rs b/src/rstd/atomic/atomic_object.rs index 906b9d1..f7596f8 100644 --- a/src/rstd/atomic/atomic_object.rs +++ b/src/rstd/atomic/atomic_object.rs @@ -81,7 +81,7 @@ impl ParseMode for AtomicFactory { impl<'a, Ctx: Context<'a>, A: AtomicModeParse> FactoryModeParse<'a, Ctx> for AtomicFactory { fn mdeserialize>(&self, inctx: I) -> ParseResultM<'a, Ctx, Self, I> { - <::Mode as Mode>::bind(A::ma_deserialize(inctx), |a| Ok(a.into())) + <::Mode as Mode>::bind(A::ma_deserialize(inctx)?, |a| Ok(a.into())) } fn mextend( @@ -97,10 +97,6 @@ impl<'a, Ctx: Context<'a>, A: AtomicModeParse> FactoryModeParse<'a, Ctx> for Ato |a| Ok(a.into()), ) } - - fn mprepare(mentionable: Self::Mtbl) -> ExtensionSourceM<'a, Ctx, Self> { - <::Mode as Mode>::smap(mentionable.atomic.ma_prepare(), |a| a.into()) - } } /// Extension trait to provide method-like utilities associated with [AtomicObject]s. diff --git a/src/rstd/atomic/modes.rs b/src/rstd/atomic/modes.rs index 9b81abc..9706bd4 100644 --- a/src/rstd/atomic/modes.rs +++ b/src/rstd/atomic/modes.rs @@ -2,28 +2,25 @@ use super::*; impl Atomic for A { fn a_deserialize(inlining: impl Inlining) -> AParseResult { - ::seal(Self::ma_deserialize(inlining)) + Self::ma_deserialize(inlining).map(::seal) } fn a_extend(self, tail: &[u8]) -> AParseResult { - ::xseal(Self::ma_extend(self.ma_prepare(), tail)) + ::xseal(Self::ma_extend(::prepare(self), tail)) } } -pub type AParseResultM = <::Mode as Mode>::ParseResult, I>; +pub type AParseResultM = ModeResult<::Mode, A, AParseError, I>; pub type AExtensionResultM = <::Mode as Mode>::ExtensionResult>; -pub type AExtensionSourceM = - <::Mode as Mode>::ExtensionSource>; +pub type AExtensionSourceM = <::Mode as Mode>::ExtensionSource; pub trait AtomicModeParse: AtomicBase + ParseMode { fn ma_deserialize(inlining: I) -> AParseResultM; fn ma_extend(atomic: AExtensionSourceM, tail: &[u8]) -> AExtensionResultM; - - fn ma_prepare(self) -> AExtensionSourceM; } pub trait AtomicModeProxy { @@ -32,8 +29,6 @@ pub trait AtomicModeProxy { fn pma_deserialize(inlining: I) -> AParseResultM; fn pma_extend(atomic: AExtensionSourceM, tail: &[u8]) -> AExtensionResultM; - - fn pma_prepare(atomic: Self::A) -> AExtensionSourceM; } impl AtomicModeParse for A @@ -47,10 +42,6 @@ where fn ma_extend(atomic: AExtensionSourceM, tail: &[u8]) -> AExtensionResultM { <::WithMode as AtomicModeProxy>::pma_extend(atomic, tail) } - - fn ma_prepare(self) -> AExtensionSourceM { - <::WithMode as AtomicModeProxy>::pma_prepare(self) - } } pub trait RegularAtomic: AtomicBase + ParseMode { @@ -68,8 +59,4 @@ impl AtomicModeProxy for WithMode { fn pma_extend(atomic: AExtensionSourceM, tail: &[u8]) -> AExtensionResultM { atomic.ra_extend(tail) } - - fn pma_prepare(atomic: Self::A) -> AExtensionSourceM { - atomic - } } diff --git a/src/rstd/collections/pair.rs b/src/rstd/collections/pair.rs index e1ab377..ff4bfdd 100644 --- a/src/rstd/collections/pair.rs +++ b/src/rstd/collections/pair.rs @@ -60,8 +60,12 @@ where (&factory_data.0, &factory_data.1) } - fn from_parsed(_factory_data: &Self::FactoryData, a: Self::A, b: Self::B) -> Self { - (a, b) + fn from_parsed( + _factory_data: &Self::FactoryData, + a: Self::A, + b: Self::B, + ) -> Result { + Ok((a, b)) } fn from_error_a( diff --git a/src/rstd/inlining/modes.rs b/src/rstd/inlining/modes.rs index 226980b..d78bee5 100644 --- a/src/rstd/inlining/modes.rs +++ b/src/rstd/inlining/modes.rs @@ -3,30 +3,30 @@ use super::*; pub struct InliningMode; impl Mode for InliningMode { - type ParseResult = Result<(A, I), E>; + type ParseSuccess = (A, I); type ExtensionResult = E; - type ExtensionSource = (); - - fn map_err( - result: Self::ParseResult, - f: impl FnOnce(E0) -> E1, - ) -> Self::ParseResult { - result.map_err(f) - } + type ExtensionSource = (); fn bind( - result: Self::ParseResult, + s: Self::ParseSuccess, f: impl FnOnce(A0) -> Result, - ) -> Self::ParseResult { - let (a0, i) = result?; + ) -> ModeResult { + let (a0, i) = s; let a1 = f(a0)?; Ok((a1, i)) } - fn seal(result: Self::ParseResult) -> Result { - result.map(|(a, _)| a) + fn map( + s: Self::ParseSuccess, + f: impl FnOnce(A0) -> A1, + ) -> Self::ParseSuccess { + (f(s.0), s.1) + } + + fn seal(s: Self::ParseSuccess) -> A { + s.0 } fn xmap_err( @@ -47,12 +47,23 @@ impl Mode for InliningMode { Err(result) } - fn smap( - source: Self::ExtensionSource, + fn smap( + source: Self::ExtensionSource, _f: impl FnOnce(A0) -> A1, - ) -> Self::ExtensionSource { + ) -> Self::ExtensionSource { source } + + fn prepare(_a: A) -> Self::ExtensionSource {} + + fn xsbind( + _ab: Self::ExtensionSource, + _t2ab: impl FnOnce(AB) -> (A, B), + ce: impl FnOnce(Self::ExtensionSource) -> Self::ExtensionResult, + _ab2t: impl FnOnce(A, B) -> Result, + ) -> Self::ExtensionResult { + ce(()) + } } 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> { f.qextension_error(tail) } - - fn pmprepare(_mentionable: Mtbl<'a, Ctx, Self::F>) -> ExtensionSourceM<'a, Ctx, Self::F> {} } impl AtomicModeProxy for WithMode { @@ -85,6 +94,4 @@ impl AtomicModeProxy for WithMode { fn pma_extend(_atomic: AExtensionSourceM, tail: &[u8]) -> AExtensionResultM { A::qa_extension_error(tail) } - - fn pma_prepare(_atomic: Self::A) -> AExtensionSourceM {} } diff --git a/src/rstd/inlining/static_pair.rs b/src/rstd/inlining/static_pair.rs index ae3e2cc..28a3b6d 100644 --- a/src/rstd/inlining/static_pair.rs +++ b/src/rstd/inlining/static_pair.rs @@ -29,7 +29,7 @@ pub trait StaticPairSerializable { /// /// Note: [`StaticPair::FA`] requires [`InliningFactory`] be implemented. pub trait StaticPair<'a, Ctx: Context<'a>>: - 'a + StaticPairSerializable + 'a + StaticPairSerializable + Sized { /// [Factory] data. May, depending on the usecase, include factory (factories) on the element(s). type FactoryData: 'a + Send + Sync + Clone; @@ -47,7 +47,11 @@ pub trait StaticPair<'a, Ctx: Context<'a>>: /// Borrow both elements' factories. fn factories(factory_data: &Self::FactoryData) -> (&Self::FA, &Self::FB); /// 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; /// Regularise the error returned while parsing the first element. fn from_error_a( factory_data: &Self::FactoryData, @@ -140,62 +144,43 @@ impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> FactoryBase<'a, Ctx> 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 = ::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> 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>(&self, inctx: I) -> ParseResultM<'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 = fb - .rdeserialize(inctx) - .map_err(|e| SP::from_error_b(&self.factory_data, e))?; - Ok(StaticPairObject { - pair: SP::from_parsed(&self.factory_data, a, b), - }) + Self::bind( + fb.mdeserialize(inctx) + .map_err(|e| SP::from_error_b(&self.factory_data, e))?, + |b| SP::from_parsed(&self.factory_data, a, b).map(|pair| StaticPairObject { pair }), + ) } - fn qrextend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> { + fn mextend( + &self, + mentionable: ExtensionSourceM<'a, Ctx, Self>, + tail: &[u8], + ) -> ExtensionResultM<'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>(&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), + ::xsbind( + mentionable, + |StaticPairObject { pair }| pair.into_elements(), + |b| { + ::xmap_err(fb.mextend(b, tail), |e| { + SP::from_error_b(&self.factory_data, e) + }) }, - 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> where SP::FA: FixedSizeFactory<'a, Ctx>, - SP::FB: FixedSizeFactory<'a, Ctx>, + SP::FB: FixedSizeFactory<'a, Ctx> + FactoryModeParse<'a, Ctx>, { fn size(&self) -> usize { 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> where 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; }