//! Provides [Atomic]-[Mentionable] interface. use std::ops::Deref; use super::*; /// Generic implementation of a [Mentionable] for [Atomic]s. #[derive(Clone)] 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, Ctx: Context<'a>, A: Atomic> Mentionable<'a, Ctx> for AtomicObject { type Fctr = AtomicFactory; fn factory(&self) -> Self::Fctr { AtomicFactory::new() } fn topology(&self) -> Hash { Ctx::hash(b"") } fn points_typed(&self, _points: &mut impl TakesPoints<'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, Ctx: Context<'a>, A: Atomic> Factory<'a, Ctx> for AtomicFactory { type Mtbl = AtomicObject; type ParseError = A::AParseError; fn deserialize(&self, dectx: &mut dyn DeCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self> { Ok(A::o_deserialise(dectx)?.into()) } fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> { Ok(A::a_extend(mentionable.atomic, tail)?.into()) } } /// Extension trait to provide method-like utilities associated with [AtomicObject]s. pub trait AtomicObjectExt: Atomic { /// 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 {}