//! Provides [Atomic]-[Mentionable] interface. use std::{marker::PhantomData, ops::Deref}; use crate::atomic::*; use super::*; /// Generic implementation of a [Mentionable] for [Atomic]s. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct AtomicObject { atomic: A, } impl From for AtomicObject { fn from(value: A) -> Self { Self { atomic: value } } } impl AsRef for AtomicObject { fn as_ref(&self) -> &A { &self.atomic } } impl Deref for AtomicObject { type Target = A; fn deref(&self) -> &Self::Target { &self.atomic } } impl Serializable for AtomicObject { fn serialize(&self, serializer: &mut dyn Serializer) { self.atomic.serialize(serializer) } } impl<'a, A: AtomicBase> MentionableBase<'a> for AtomicObject { type Fctr = AtomicFactory; fn factory(&self) -> Self::Fctr { AtomicFactory::new() } } impl<'a, Ctx: Context<'a>, A: AtomicBase> MentionableTop<'a, Ctx> for AtomicObject { fn topology_hash(&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 { _pd: PhantomData, } impl AtomicFactory { fn new() -> Self { AtomicFactory { _pd: PhantomData } } } impl Clone for AtomicFactory { fn clone(&self) -> Self { Self::new() } } impl<'a, A: AtomicBase> FactoryBase<'a> for AtomicFactory { type Mtbl = AtomicObject; type ParseError = A::AParseError; } impl ParseMode for AtomicFactory { type Mode = A::Mode; } impl<'a, Ctx: Context<'a>, A: AtomicModeParse> FactoryModeParse<'a, Ctx> for AtomicFactory { fn mdeserialize>(&self, inctx: I) -> ModeResultM<'a, Self, I> { A::ma_deserialize(inctx).map(|a| Self::map(a, From::from)) } fn mextend( &self, mentionable: ExtensionSourceM<'a, Self>, tail: &[u8], ) -> ExtensionResultM<'a, 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 { AtomicFactory::new() } /// Shorthand for getting specific [`AtomicObject`]. fn m(self) -> AtomicObject { self.into() } } impl AtomicObjectExt for A {}