//! Pair implementation based on [`StaticPair`]. use std::error::Error; use std::fmt::Display; use crate::atomic::*; use crate::mode::*; use crate::rcore::*; use crate::rstd::inlining::static_pair::*; use crate::rstd::inlining::*; pub type PairObject = StaticPairObject<(A, B)>; pub type PairFactory<'a, Ctx, A, B> = StaticPairFactory<'a, Ctx, (A, B)>; impl StaticPairSerializable for (A, B) { type SA = A; type SB = B; fn elements(&self) -> (&Self::SA, &Self::SB) { (&self.0, &self.1) } fn into_elements(self) -> (Self::SA, Self::SB) { self } } #[derive(Debug)] pub enum PairParseError { A(ErrorA), B(ErrorB), } impl Display for PairParseError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::A(error) => { write!(f, "error while parsing first element of a pair: {}", error) } Self::B(error) => { write!(f, "error while parsing second element of a pair: {}", error) } } } } impl Error for PairParseError {} impl<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>, B: MentionableBase<'a, Ctx>> StaticPair<'a, Ctx> for (A, B) where A::Fctr: ParseMode, B::Fctr: ParseMode, { type FactoryData = (Self::FA, Self::FB); type A = A; type B = B; type FA = A::Fctr; type FB = B::Fctr; type ParseError = PairParseError, ParseError<'a, Ctx, B::Fctr>>; fn factories(factory_data: &Self::FactoryData) -> (&Self::FA, &Self::FB) { (&factory_data.0, &factory_data.1) } fn from_parsed( _factory_data: &Self::FactoryData, a: Self::A, b: Self::B, ) -> Result { Ok((a, b)) } fn from_error_a( _factory_data: &Self::FactoryData, error: ParseError<'a, Ctx, Self::FA>, ) -> Self::ParseError { PairParseError::A(error) } fn from_error_b( _factory_data: &Self::FactoryData, error: ParseError<'a, Ctx, Self::FB>, ) -> Self::ParseError { PairParseError::B(error) } fn factory_data(&self) -> Self::FactoryData { (self.0.factory(), self.1.factory()) } } impl StaticPairAtomic for (A, B) { type A = A; type B = B; type AParseError = PairParseError; fn from_parsed(a: Self::A, b: Self::B) -> Result { Ok((a, b)) } fn from_error_a(error: AParseError) -> Self::AParseError { PairParseError::A(error) } fn from_error_b(error: AParseError) -> Self::AParseError { PairParseError::B(error) } } impl Serializable for (A, B) { fn serialize(&self, serializer: &mut dyn Serializer) { StaticPairObject::::serialize_sp(self, serializer) } } impl<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>, B: MentionableBase<'a, Ctx>> MentionableBase<'a, Ctx> for (A, B) { type Fctr = (A::Fctr, B::Fctr); fn factory(&self) -> Self::Fctr { (self.0.factory(), self.1.factory()) } } impl<'a, Ctx: Context<'a>, FA: FactoryBase<'a, Ctx>, FB: FactoryBase<'a, Ctx>> FactoryBase<'a, Ctx> for (FA, FB) { type Mtbl = (FA::Mtbl, FB::Mtbl); type ParseError = PairParseError; } impl AtomicBase for (A, B) { type AParseError = PairParseError; } impl ParseMode for (A, B) { type Mode = B::Mode; } type PFImpl<'a, Ctx, FA, FB> = StaticPairFactory< 'a, Ctx, ( >::Mtbl, >::Mtbl, ), >; impl<'a, Ctx: Context<'a>, FA: InliningFactory<'a, Ctx>, FB: FactoryModeParse<'a, Ctx>> FactoryModeParse<'a, Ctx> for (FA, FB) { fn mdeserialize>(&self, inctx: I) -> ModeResultM<'a, Ctx, Self, I> { PFImpl::<'a, Ctx, FA, FB>::mdeserialize_sp(self, inctx) } fn mextend( &self, mentionable: ExtensionSourceM<'a, Ctx, Self>, tail: &[u8], ) -> ExtensionResultM<'a, Ctx, Self> { PFImpl::<'a, Ctx, FA, FB>::mextend_sp(self, mentionable, tail) } } impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, B: Mentionable<'a, Ctx>> MentionableTop<'a, Ctx> for (A, B) { fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) { StaticPairObject::::points_typed_sp(self, points) } } impl<'a, Ctx: Context<'a>, FA, FB> FixedSizeFactory<'a, Ctx> for (FA, FB) where FA: FixedSizeFactory<'a, Ctx>, FB: FixedSizeFactory<'a, Ctx> + FactoryModeParse<'a, Ctx>, { fn size(&self) -> usize { self.0.size() + self.1.size() } } impl AtomicModeParse for (A, B) { fn ma_deserialize(stream: I) -> AModeResultM { StaticPairObject::::ma_deserialize_sp(stream) } fn ma_extend(atomic: AExtensionSourceM, tail: &[u8]) -> AExtensionResultM { StaticPairObject::::ma_extend_sp(atomic, tail) } }