119 lines
3.0 KiB
Rust
119 lines
3.0 KiB
Rust
//! 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 as ParseMode>::Mode as Mode>::bind(A::ma_deserialize(inctx), |a| Ok(a.into()))
|
|
}
|
|
|
|
fn mextend(
|
|
&self,
|
|
mentionable: ExtensionSourceM<'a, Ctx, Self>,
|
|
tail: &[u8],
|
|
) -> ExtensionResultM<'a, Ctx, Self> {
|
|
<<A as ParseMode>::Mode as Mode>::xbind(
|
|
A::ma_extend(
|
|
<<A as ParseMode>::Mode as Mode>::smap(mentionable, |a| a.atomic),
|
|
tail,
|
|
),
|
|
|a| Ok(a.into()),
|
|
)
|
|
}
|
|
|
|
fn mprepare(mentionable: Self::Mtbl) -> ExtensionSourceM<'a, Ctx, Self> {
|
|
<<A as ParseMode>::Mode as Mode>::smap(mentionable.atomic.ma_prepare(), |a| 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 {}
|