//! Provides [Atomic]-[Mentionable] interface. use std::ops::Deref; use super::*; /// Generic implementation of a [Mentionable] for [Atomic]s. #[derive(Clone)] pub struct AtomicObject<A: AtomicBase> { atomic: A, } impl<A: AtomicBase> From<A> for AtomicObject<A> { fn from(value: A) -> Self { Self { atomic: value } } } impl<A: AtomicBase> AsRef<A> for AtomicObject<A> { fn as_ref(&self) -> &A { &self.atomic } } impl<A: AtomicBase> Deref for AtomicObject<A> { type Target = A; fn deref(&self) -> &Self::Target { &self.atomic } } impl<A: AtomicBase> Serializable for AtomicObject<A> { fn serialize(&self, serializer: &mut dyn Serializer) { self.atomic.serialize(serializer) } } impl<'a, Ctx: Context<'a>, A: AtomicBase> MentionableBase<'a, Ctx> for AtomicObject<A> { type Fctr = AtomicFactory<A>; fn factory(&self) -> Self::Fctr { AtomicFactory::new() } } impl<'a, Ctx: Context<'a>, A: AtomicBase> MentionableTop<'a, Ctx> for AtomicObject<A> { fn topology(&self) -> Hash { Ctx::hash(b"") } fn points_typed(&self, _points: &mut impl PointsVisitor<'a, Ctx>) {} } /// Generic implementation of a [Factory] for [Atomic]s. pub struct AtomicFactory<A> { _pd: PhantomData<A>, } impl<A> AtomicFactory<A> { fn new() -> Self { AtomicFactory { _pd: PhantomData } } } impl<A: AtomicBase> Clone for AtomicFactory<A> { fn clone(&self) -> Self { Self::new() } } impl<'a, Ctx: Context<'a>, A: AtomicBase> FactoryBase<'a, Ctx> for AtomicFactory<A> { type Mtbl = AtomicObject<A>; type ParseError = A::AParseError; } impl<A: ParseMode> ParseMode for AtomicFactory<A> { type Mode = A::Mode; } impl<'a, Ctx: Context<'a>, A: AtomicModeParse> FactoryModeParse<'a, Ctx> for AtomicFactory<A> { fn mdeserialize<I: InCtx<'a, Ctx>>(&self, inctx: I) -> ParseResultM<'a, Ctx, Self, I> { A::ma_deserialize(inctx).map(|a| Self::map(a, From::from)) } fn mextend( &self, mentionable: ExtensionSourceM<'a, Ctx, Self>, tail: &[u8], ) -> ExtensionResultM<'a, Ctx, Self> { Self::xbind( A::ma_extend(Self::smap(mentionable, |a| a.atomic), tail), |a| Ok(a.into()), ) } } /// Extension trait to provide method-like utilities associated with [AtomicObject]s. pub trait AtomicObjectExt: AtomicBase { /// Shorthand for getting specific [`AtomicFactory`]. fn f() -> AtomicFactory<Self> { AtomicFactory::new() } /// Shorthand for getting specific [`AtomicObject`]. fn m(self) -> AtomicObject<Self> { self.into() } } impl<A: AtomicBase> AtomicObjectExt for A {}