diff --git a/src/core.rs b/src/core.rs index 89509de..9bef2ff 100644 --- a/src/core.rs +++ b/src/core.rs @@ -86,7 +86,7 @@ pub type ParseResult<'a, Ctx, F> = /// Trait representing deserialisation rules for [Mentionable]s. /// Crucial for [`TypelessMentionable`] and therefore [`Mentionable::points`]. -pub trait Factory<'a, Ctx: 'a + Context>: 'a + Clone { +pub trait Factory<'a, Ctx: 'a + Context>: 'a + Send + Sync + Clone { /// Type of the associated objects. type Mtbl: Mentionable<'a, Ctx, Fctr = Self>; /// Type of an error that [`Factory::deserialize`] can fail with. diff --git a/src/core/typeless.rs b/src/core/typeless.rs index 8367306..6253303 100644 --- a/src/core/typeless.rs +++ b/src/core/typeless.rs @@ -12,15 +12,31 @@ pub struct TypelessMentionable<'a, Ctx: 'a + Context> { type TypelessParsed<'a, Ctx> = Result, Box>; -type TypelessDeserialize<'a, Ctx> = dyn 'a - + Fn(&mut dyn Deserializer, Rc>, &mut Addresses) -> TypelessParsed<'a, Ctx>; +trait Tde<'a, Ctx: 'a + Context>: 'a + Send + Sync { + fn clone_box(&self) -> TdeBox<'a, Ctx>; -type TypelessUnexpectedTail<'a> = dyn 'a + Fn(&[u8]) -> TypelessError<'a>; + 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 [`Mentionable::points`]/[`TypelessMentionable`]. pub struct TypelessFactory<'a, Ctx: 'a + Context> { - t_deserialize: Rc>, - t_unexpected_tail: Rc>, + t_deserialize: TdeBox<'a, Ctx>, + t_unexpected_tail: TutBox<'a, Ctx>, } impl<'a, Ctx: 'a + Context> Serializable for TypelessMentionable<'a, Ctx> { @@ -52,8 +68,8 @@ impl<'a, Ctx: 'a + Context> Mentionable<'a, Ctx> for TypelessMentionable<'a, Ctx impl<'a, Ctx: 'a + Context> Clone for TypelessFactory<'a, Ctx> { fn clone(&self) -> Self { Self { - t_deserialize: self.t_deserialize.clone(), - t_unexpected_tail: self.t_unexpected_tail.clone(), + t_deserialize: self.t_deserialize.clone_box(), + t_unexpected_tail: self.t_unexpected_tail.clone_box(), } } } @@ -81,14 +97,14 @@ impl<'a, Ctx: 'a + Context> Factory<'a, Ctx> for TypelessFactory<'a, Ctx> { resolver: Rc>, addresses: &mut Addresses, ) -> ParseResult<'a, Ctx, Self> { - match (self.t_deserialize)(deserializer, resolver, addresses) { + 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)(tail) + self.t_unexpected_tail.ut(tail) } } @@ -106,19 +122,42 @@ impl<'a, Ctx: 'a + Context> TypelessMentionable<'a, Ctx> { } } +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 { - let tail_factory = factory.clone(); TypelessFactory { - t_deserialize: Rc::new(move |deserializer, resolver, addresses| { - match factory.deserialize(deserializer, resolver, addresses) { - Ok(mentionable) => Ok(TypelessMentionable::from_typed(Rc::new(mentionable))), - Err(error) => Err(Box::new(error)), - } - }), - t_unexpected_tail: Rc::new(move |tail| { - TypelessError::from_typed(tail_factory.unexpected_tail(tail)) - }), + t_deserialize: Box::new(factory.clone()), + t_unexpected_tail: Box::new(factory), } } } diff --git a/src/std/atomic.rs b/src/std/atomic.rs index ae792ab..75c2581 100644 --- a/src/std/atomic.rs +++ b/src/std/atomic.rs @@ -13,7 +13,7 @@ use super::*; /// This trait combines functionality of [`Mentionable`] and [`Factory`], /// while limiting [`Mentionable::points`] (and corresponding [`Mentionable::topology`]) to an empty sequence. -pub trait Atomic: 'static + Sized + Clone + Serializable { +pub trait Atomic: 'static + Send + Sync + Send + Clone + Serializable { /// Equivalent of [`Factory::ParseError`]. type ParseError: Error; /// Static equivalent of [`Factory::deserialize`]. diff --git a/src/std/inlining/static_pair.rs b/src/std/inlining/static_pair.rs index fae1b6c..a7c1255 100644 --- a/src/std/inlining/static_pair.rs +++ b/src/std/inlining/static_pair.rs @@ -31,7 +31,7 @@ pub trait StaticPair<'a, Ctx: 'a + Context>: 'a + StaticPairSerializable { /// [Factory] data. May, depending on the usecase, include factory (factories) on the element(s). - type FactoryData: 'a + Clone; + type FactoryData: 'a + Send + Sync + Clone; /// First element's type. Must equal [`StaticPairSerializable::SA`]. type A: Mentionable<'a, Ctx, Fctr = Self::FA>; /// Second element's type. Must equal [`StaticPairSerializable::SB`].