//! Previously part of [`crate::rcore`]. use super::{wrapped_origin::*, *}; type TypelessSerialize<'a> = dyn 'a + Fn(&mut dyn Serializer); /// See [`Point::typeless`]. pub struct TypelessMentionable<'a, Ctx: 'a + Context> { t_serialize: Box>, t_factory: TypelessFactory<'a, Ctx>, t_topology: Hash, t_points: Vec>>, } type TypelessParsed<'a, Ctx> = Result, Box>; trait Tde<'a, Ctx: 'a + Context>: 'a + Send + Sync { fn clone_box(&self) -> TdeBox<'a, Ctx>; fn de( &self, deserializer: &mut dyn Deserializer, resolver: Rc>, addresses: &mut Addresses, ) -> TypelessParsed<'a, Ctx>; } type TdeBox<'a, Ctx> = Box>; trait Tut<'a, Ctx: 'a + Context>: 'a + Send + Sync { fn clone_box(&self) -> TutBox<'a, Ctx>; fn ut(&self, tail: &[u8]) -> TypelessError<'a>; } type TutBox<'a, Ctx> = Box>; /// See [`Point::typeless`]/[`TypelessMentionable`]. pub struct TypelessFactory<'a, Ctx: 'a + Context> { t_deserialize: TdeBox<'a, Ctx>, t_unexpected_tail: TutBox<'a, Ctx>, } impl<'a, Ctx: 'a + Context> Serializable for TypelessMentionable<'a, Ctx> { fn serialize(&self, serializer: &mut dyn Serializer) { (self.t_serialize)(serializer); } } impl<'a, Ctx: 'a + Context> Mentionable<'a, Ctx> for TypelessMentionable<'a, Ctx> { type Fctr = TypelessFactory<'a, Ctx>; fn factory(&self) -> Self::Fctr { self.t_factory.clone() } fn topology(&self) -> Hash { self.t_topology } fn points_typed(&self, points: &mut impl TakesPoints<'a, Ctx>) { for point in self.t_points.iter() { points.take(point) } } } impl<'a, Ctx: 'a + Context> Clone for TypelessFactory<'a, Ctx> { fn clone(&self) -> Self { Self { t_deserialize: self.t_deserialize.clone_box(), t_unexpected_tail: self.t_unexpected_tail.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 { f.write_fmt(format_args!("typeless error: {}", self.0)) } } impl<'a> Error for TypelessError<'a> {} impl<'a, Ctx: 'a + Context> Factory<'a, Ctx> for TypelessFactory<'a, Ctx> { type Mtbl = TypelessMentionable<'a, Ctx>; type ParseError = TypelessError<'a>; fn deserialize( &self, deserializer: &mut dyn Deserializer, resolver: Rc>, addresses: &mut Addresses, ) -> ParseResult<'a, Ctx, Self> { match self.t_deserialize.de(deserializer, resolver, addresses) { Ok(mentionable) => Ok(mentionable), Err(error) => Err(TypelessError(error)), } } fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError { self.t_unexpected_tail.ut(tail) } } impl<'a, Ctx: 'a + Context> TypelessMentionable<'a, Ctx> { 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: 'a + Context, F: Factory<'a, Ctx>> Tde<'a, Ctx> for F { fn clone_box(&self) -> TdeBox<'a, Ctx> { Box::new(self.clone()) } fn de( &self, deserializer: &mut dyn Deserializer, resolver: Rc>, addresses: &mut Addresses, ) -> TypelessParsed<'a, Ctx> { match self.deserialize(deserializer, resolver, addresses) { Ok(mentionable) => Ok(TypelessMentionable::from_typed(Rc::new(mentionable))), Err(error) => { let boxed: Box = Box::new(error); Err(boxed) } } } } impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Tut<'a, Ctx> for F { fn clone_box(&self) -> TutBox<'a, Ctx> { Box::new(self.clone()) } fn ut(&self, tail: &[u8]) -> TypelessError<'a> { TypelessError::from_typed(self.unexpected_tail(tail)) } } impl<'a, Ctx: 'a + Context> TypelessFactory<'a, Ctx> { pub fn from_typed>(factory: F) -> Self { TypelessFactory { t_deserialize: Box::new(factory.clone()), t_unexpected_tail: Box::new(factory), } } } impl<'a> TypelessError<'a> { pub fn from_typed(error: E) -> Self { TypelessError(Box::new(error)) } } impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> { /// 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: 'a + Context>: Mentionable<'a, Ctx> { /// References ([Point]s) to other objects. Typeless. fn points_typeless(&self, points: &mut Vec>>); /// [Vec] of [Point]s as used by [`Mentionable::topology`]. fn points_vec(&self) -> Vec>>; } impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> MentionableExt<'a, Ctx> for A { 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: 'a + Context> TakesPoints<'a, Ctx> for Vec>> { fn take>(&mut self, point: &Point<'a, Ctx, A>) { self.push(point.typeless()); } }