//! Previously part of [`crate::rcore`]. use super::{cast::CastError, wrapped_origin::*, *}; type TypelessSerialize<'a> = dyn 'a + Fn(&mut dyn Serializer); /// See [`Point::typeless`]. pub struct TypelessMentionable<'a, Ctx: Context<'a>> { t_serialize: Box>, t_factory: TypelessFactory<'a, Ctx>, t_topology: Hash, t_points: Vec>>, } type TypelessParsed<'a, Ctx> = Result, Box>; trait Tde<'a, Ctx: Context<'a>>: 'a + Send + Sync { fn clone_box(&self) -> TdeBox<'a, Ctx>; fn de<'c>(&self, demoted: Demoted<'a, 'c, Ctx>) -> TypelessParsed<'a, Ctx> where 'a: 'c; } type TdeBox<'a, Ctx> = Box>; trait Tut<'a, Ctx: Context<'a>>: 'a + Send + Sync { fn clone_box(&self) -> TutBox<'a, Ctx>; fn xt( &self, mentionable: TypelessMentionable<'a, Ctx>, tail: &[u8], ) -> Result, TypelessError<'a>>; } type TutBox<'a, Ctx> = Box>; /// See [`Point::typeless`]/[`TypelessMentionable`]. pub struct TypelessFactory<'a, Ctx: Context<'a>> { t_deserialize: TdeBox<'a, Ctx>, t_extend: TutBox<'a, Ctx>, } impl<'a, Ctx: Context<'a>> Serializable for TypelessMentionable<'a, Ctx> { fn serialize(&self, serializer: &mut dyn Serializer) { (self.t_serialize)(serializer); } } impl<'a, Ctx: Context<'a>> MentionableBase<'a, Ctx> for TypelessMentionable<'a, Ctx> { type Fctr = TypelessFactory<'a, Ctx>; fn factory(&self) -> Self::Fctr { self.t_factory.clone() } } impl<'a, Ctx: Context<'a>> MentionableTop<'a, Ctx> for TypelessMentionable<'a, Ctx> { fn topology(&self) -> Hash { self.t_topology } fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) { for point in self.t_points.iter() { points.visit(point) } } } impl<'a, Ctx: Context<'a>> Clone for TypelessFactory<'a, Ctx> { fn clone(&self) -> Self { Self { t_deserialize: self.t_deserialize.clone_box(), t_extend: self.t_extend.clone_box(), } } } /// See [`Point::typeless`]/[`TypelessFactory`]. #[derive(Debug)] pub struct TypelessError<'a>(Box); impl<'a> Display for TypelessError<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "typeless error: {}", self.0) } } impl<'a> Error for TypelessError<'a> {} impl<'a, Ctx: Context<'a>> FactoryBase<'a, Ctx> for TypelessFactory<'a, Ctx> { type Mtbl = TypelessMentionable<'a, Ctx>; type ParseError = TypelessError<'a>; } impl<'a, Ctx: Context<'a>> ParseMode for TypelessFactory<'a, Ctx> { type Mode = RegularMode; } impl<'a, Ctx: Context<'a>> RegularFactory<'a, Ctx> for TypelessFactory<'a, Ctx> { fn rdeserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self> { self.t_deserialize.de(inctx.demote()).map_err(TypelessError) } fn rextend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> { self.t_extend.xt(mentionable, tail) } } impl<'a, Ctx: Context<'a>> TypelessMentionable<'a, Ctx> where Ctx::LookupError: From>, { pub fn from_typed>(mentionable: Rc) -> Self { let factory = TypelessFactory::from_typed(mentionable.factory()); let topology = mentionable.topology(); let points = mentionable.points_vec(); TypelessMentionable { t_serialize: Box::new(move |serializer| mentionable.serialize(serializer)), t_factory: factory, t_topology: topology, t_points: points, } } } impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Tde<'a, Ctx> for F where Ctx::LookupError: From>, { fn clone_box(&self) -> TdeBox<'a, Ctx> { Box::new(self.clone()) } fn de<'c>(&self, demoted: Demoted<'a, 'c, Ctx>) -> TypelessParsed<'a, Ctx> where 'a: 'c, { self.deserialize(demoted) .map_err(|e| Box::new(e) as _) .map(Rc::new) .map(TypelessMentionable::from_typed) } } impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Tut<'a, Ctx> for F where Ctx::LookupError: From>, { fn clone_box(&self) -> TutBox<'a, Ctx> { Box::new(self.clone()) } fn xt( &self, mentionable: TypelessMentionable<'a, Ctx>, tail: &[u8], ) -> Result, TypelessError<'a>> { self.extend( match mentionable.cast(self.clone()) { Ok(m) => m, Err(e) => return Err(TypelessError::from_typed(e)), }, tail, ) .map_err(TypelessError::from_typed) .map(Rc::new) .map(TypelessMentionable::from_typed) } } impl<'a, Ctx: Context<'a>> TypelessFactory<'a, Ctx> where Ctx::LookupError: From>, { pub fn from_typed>(factory: F) -> Self { TypelessFactory { t_deserialize: Box::new(factory.clone()), t_extend: Box::new(factory), } } } impl<'a> TypelessError<'a> { pub fn from_typed(error: E) -> Self { TypelessError(Box::new(error)) } } impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> where Ctx::LookupError: From>, { /// Typeless version of the point. pub fn typeless(&self) -> Point<'a, Ctx, TypelessMentionable<'a, Ctx>> { Point { point: self.point, origin: self.origin.clone().map( TypelessMentionable::from_typed, TypelessError::from_typed, TypelessFactory::from_typed, ), } } } pub trait MentionableExt<'a, Ctx: Context<'a>>: Mentionable<'a, Ctx> { /// References ([Point]s) to other objects. Typeless. fn points_typeless(&self, points: &mut Vec>>); /// [Vec] of [Point]s as used by [`MentionableTop::topology`]. fn points_vec(&self) -> Vec>>; } impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableExt<'a, Ctx> for A where Ctx::LookupError: From>, { fn points_typeless(&self, points: &mut Vec>>) { self.points_typed(points) } fn points_vec(&self) -> Vec>> { let mut points = Vec::new(); self.points_typeless(&mut points); points } } impl<'a, Ctx: Context<'a>> PointsVisitor<'a, Ctx> for Vec>> where Ctx::LookupError: From>, { fn visit>(&mut self, point: &Point<'a, Ctx, A>) { self.push(point.typeless()); } }