MentionableTop

This commit is contained in:
AF 2023-07-29 08:46:35 +00:00
parent 7ebc5ba615
commit c6b3029798
14 changed files with 43 additions and 15 deletions

View File

@ -55,6 +55,9 @@ pub trait MentionableBase<'a, Ctx: Context<'a>>: 'a + Serializable + Sized {
/// Value of the associated factory. /// Value of the associated factory.
fn factory(&self) -> Self::Fctr; fn factory(&self) -> Self::Fctr;
}
pub trait MentionableTop<'a, Ctx: Context<'a>>: 'a {
/// See implementation for the definition. /// See implementation for the definition.
/// Hash of all the references' points concatenated, ordered, non-unique. /// Hash of all the references' points concatenated, ordered, non-unique.
/// Used for walking over object trees to ensure two objects with different references don't collide. /// Used for walking over object trees to ensure two objects with different references don't collide.
@ -67,11 +70,14 @@ pub trait MentionableBase<'a, Ctx: Context<'a>>: 'a + Serializable + Sized {
fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>); fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>);
} }
pub trait Mentionable<'a, Ctx: Context<'a>>: MentionableBase<'a, Ctx, Fctr = Self::_Fctr> { pub trait Mentionable<'a, Ctx: Context<'a>>:
MentionableBase<'a, Ctx, Fctr = Self::_Fctr> + MentionableTop<'a, Ctx>
{
type _Fctr: Factory<'a, Ctx, Mtbl = Self>; type _Fctr: Factory<'a, Ctx, Mtbl = Self>;
} }
impl<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> Mentionable<'a, Ctx> for A impl<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx> + MentionableTop<'a, Ctx>>
Mentionable<'a, Ctx> for A
where where
Self::Fctr: Factory<'a, Ctx>, Self::Fctr: Factory<'a, Ctx>,
{ {
@ -90,7 +96,7 @@ pub type ParseResultA<'a, Ctx, A> = Result<A, ParseErrorA<'a, Ctx, A>>;
/// [Factory] base. /// [Factory] base.
pub trait FactoryBase<'a, Ctx: Context<'a>>: 'a + Send + Sync + Clone { pub trait FactoryBase<'a, Ctx: Context<'a>>: 'a + Send + Sync + Clone {
/// Type of the associated objects. /// Type of the associated objects.
type Mtbl: MentionableBase<'a, Ctx, Fctr = Self>; type Mtbl: MentionableBase<'a, Ctx, Fctr = Self> + MentionableTop<'a, Ctx>;
/// Type of an error that [`Factory::deserialize`] can fail with. /// Type of an error that [`Factory::deserialize`] can fail with.
type ParseError: 'a + Error; type ParseError: 'a + Error;
} }

View File

@ -3,7 +3,7 @@ use super::*;
/// Represents a potentially resolvable [`Mentionable`]. /// Represents a potentially resolvable [`Mentionable`].
pub trait Origin<'a, Ctx: Context<'a>>: 'a { pub trait Origin<'a, Ctx: Context<'a>>: 'a {
/// Type of the associated object. /// Type of the associated object.
type Mtbl: MentionableBase<'a, Ctx>; type Mtbl: MentionableBase<'a, Ctx> + MentionableTop<'a, Ctx>;
/// Clone the associated factory. /// Clone the associated factory.
fn factory(&self) -> OFctr<'a, Ctx, Self>; fn factory(&self) -> OFctr<'a, Ctx, Self>;
/// Try resolving the value. /// Try resolving the value.

View File

@ -4,7 +4,7 @@ use super::*;
pub struct Point<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> { pub struct Point<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> {
/// Hash of the referred content. /// Hash of the referred content.
/// Derived both from the serialised value ([`Serializable::serialize`]) /// Derived both from the serialised value ([`Serializable::serialize`])
/// and its topology ([`MentionableBase::topology`]). /// and its topology ([`MentionableTop::topology`]).
pub point: Hash, pub point: Hash,
/// [Origin] used in [`Point::resolve`]. /// [Origin] used in [`Point::resolve`].
pub origin: Rc<dyn Origin<'a, Ctx, Mtbl = A>>, pub origin: Rc<dyn Origin<'a, Ctx, Mtbl = A>>,

View File

@ -1,13 +1,13 @@
use super::*; use super::*;
/// Visitor used in [`MentionableBase::points_typed`]. /// Visitor used in [`MentionableTop::points_typed`].
pub trait PointsVisitor<'a, Ctx: Context<'a>> { pub trait PointsVisitor<'a, Ctx: Context<'a>> {
/// Visit a [Point]. /// Visit a [Point].
fn visit<A: Mentionable<'a, Ctx>>(&mut self, point: &Point<'a, Ctx, A>); fn visit<A: Mentionable<'a, Ctx>>(&mut self, point: &Point<'a, Ctx, A>);
} }
impl<'a, Ctx: Context<'a>> PointsVisitor<'a, Ctx> for Vec<u8> { impl<'a, Ctx: Context<'a>> PointsVisitor<'a, Ctx> for Vec<u8> {
/// The only natural implementation, as used in [`MentionableBase::topology`]. /// The only natural implementation, as used in [`MentionableTop::topology`].
fn visit<A: Mentionable<'a, Ctx>>(&mut self, point: &Point<'a, Ctx, A>) { fn visit<A: Mentionable<'a, Ctx>>(&mut self, point: &Point<'a, Ctx, A>) {
self.extend(point.point) self.extend(point.point)
} }

View File

@ -44,14 +44,14 @@ pub type HashResolution<'a, Ctx> = Wrapped<'a, Ctx, HashResolutionResult<'a, Ctx
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct Address { pub struct Address {
pub point: Hash, pub point: Hash,
/// Index of the point in the [`MentionableBase::points_typed()`]. /// Index of the point in the [`MentionableTop::points_typed()`].
pub index: usize, pub index: usize,
} }
/// Trait representing the "rainbow table" behaviour. /// Trait representing the "rainbow table" behaviour.
pub trait Resolver<'a, Ctx: Context<'a>>: 'a { pub trait Resolver<'a, Ctx: Context<'a>>: 'a {
/// Successfully returned value should be the inverse of the point passed /// Successfully returned value should be the inverse of the point passed
/// with topology header ([`MentionableBase::topology()`]) omitted. /// with topology header ([`MentionableTop::topology()`]) omitted.
fn resolve(self: Rc<Self>, address: Address) -> HashResolution<'a, Ctx>; fn resolve(self: Rc<Self>, address: Address) -> HashResolution<'a, Ctx>;
} }

View File

@ -21,7 +21,7 @@ pub type AParseError<A> = <A as AtomicBase>::AParseError;
pub type AParseResult<A> = Result<A, AParseError<A>>; pub type AParseResult<A> = Result<A, AParseError<A>>;
/// This trait combines functionality of [`Mentionable`] and [`Factory`], /// This trait combines functionality of [`Mentionable`] and [`Factory`],
/// while limiting [`MentionableBase::points_typed`] (and corresponding [`MentionableBase::topology`]) /// while limiting [`MentionableTop::points_typed`] (and corresponding [`MentionableTop::topology`])
/// to an empty sequence. /// to an empty sequence.
pub trait AtomicBase: 'static + Send + Sync + Send + Clone + Serializable { pub trait AtomicBase: 'static + Send + Sync + Send + Clone + Serializable {
/// Equivalent of [`FactoryBase::ParseError`]. /// Equivalent of [`FactoryBase::ParseError`].

View File

@ -37,7 +37,7 @@ impl<A: AtomicBase> Serializable for AtomicObject<A> {
} }
pub trait AoProxy<'a, Ctx: Context<'a>>: AtomicProxy { pub trait AoProxy<'a, Ctx: Context<'a>>: AtomicProxy {
type Mtbl: MentionableBase<'a, Ctx, Fctr = Self::Fctr>; type Mtbl: MentionableBase<'a, Ctx, Fctr = Self::Fctr> + MentionableTop<'a, Ctx>;
type Fctr: Factory<'a, Ctx, Mtbl = Self::Mtbl>; type Fctr: Factory<'a, Ctx, Mtbl = Self::Mtbl>;
fn factory() -> Self::Fctr; fn factory() -> Self::Fctr;
@ -54,7 +54,9 @@ where
fn factory(&self) -> Self::Fctr { fn factory(&self) -> Self::Fctr {
<A::WithMode as AoProxy<'a, Ctx>>::factory() <A::WithMode as AoProxy<'a, Ctx>>::factory()
} }
}
impl<'a, Ctx: Context<'a>, A: AtomicBase> MentionableTop<'a, Ctx> for AtomicObject<A> {
fn topology(&self) -> Hash { fn topology(&self) -> Hash {
Ctx::hash(b"") Ctx::hash(b"")
} }

View File

@ -24,7 +24,7 @@ pub enum CastError<'a> {
/// If you don't know what that means, it's a good idea to [`panic!`]. /// If you don't know what that means, it's a good idea to [`panic!`].
/// Happens due to internal resolver using indices rather than `point`s. /// Happens due to internal resolver using indices rather than `point`s.
/// This error usually indicates inconsistent behaviour /// This error usually indicates inconsistent behaviour
/// of [`MentionableBase::points_typed`] and/or [`MentionableBase::topology`]. /// of [`MentionableTop::points_typed`] and/or [`MentionableTop::topology`].
AddressIndexOutOfBounds { AddressIndexOutOfBounds {
index: usize, index: usize,
length: usize, length: usize,

View File

@ -86,7 +86,11 @@ impl<'a, Ctx: Context<'a>, A: StackCompatible<'a, Ctx>> MentionableBase<'a, Ctx>
fn factory(&self) -> Self::Fctr { fn factory(&self) -> Self::Fctr {
StackNodeFactory::new(self.element.factory()) StackNodeFactory::new(self.element.factory())
} }
}
impl<'a, Ctx: Context<'a>, A: StackCompatible<'a, Ctx>> MentionableTop<'a, Ctx>
for StackNode<'a, Ctx, A>
{
fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) { fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) {
<A as StackCompatible<'a, Ctx>>::points_typed_rest(&self.rest, points); <A as StackCompatible<'a, Ctx>>::points_typed_rest(&self.rest, points);
self.element.points_typed(points); self.element.points_typed(points);

View File

@ -106,7 +106,9 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableBase<'a, Ctx> for
fn factory(&self) -> Self::Fctr { fn factory(&self) -> Self::Fctr {
NodeFactory(self.key.factory()) NodeFactory(self.key.factory())
} }
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableTop<'a, Ctx> for Node<'a, Ctx, A> {
fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) { fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) {
self.l.points_typed(points); self.l.points_typed(points);
self.r.points_typed(points); self.r.points_typed(points);
@ -120,7 +122,9 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableBase<'a, Ctx> for
fn factory(&self) -> Self::Fctr { fn factory(&self) -> Self::Fctr {
TreeFactory(self.node.factory()) TreeFactory(self.node.factory())
} }
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableTop<'a, Ctx> for Tree<'a, Ctx, A> {
fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) { fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) {
self.node.points_typed(points); self.node.points_typed(points);
} }

View File

@ -34,9 +34,9 @@ pub trait StaticPair<'a, Ctx: Context<'a>>:
/// [Factory] data. May, depending on the usecase, include factory (factories) on the element(s). /// [Factory] data. May, depending on the usecase, include factory (factories) on the element(s).
type FactoryData: 'a + Send + Sync + Clone; type FactoryData: 'a + Send + Sync + Clone;
/// First element's type. Must equal [`StaticPairSerializable::SA`]. /// First element's type. Must equal [`StaticPairSerializable::SA`].
type A: MentionableBase<'a, Ctx, Fctr = Self::FA>; type A: MentionableBase<'a, Ctx, Fctr = Self::FA> + MentionableTop<'a, Ctx>;
/// Second element's type. Must equal [`StaticPairSerializable::SB`]. /// Second element's type. Must equal [`StaticPairSerializable::SB`].
type B: MentionableBase<'a, Ctx, Fctr = Self::FB>; type B: MentionableBase<'a, Ctx, Fctr = Self::FB> + MentionableTop<'a, Ctx>;
/// First element's factory. /// First element's factory.
type FA: FactoryBase<'a, Ctx, Mtbl = Self::A> + InlineableFactory<'a, Ctx>; type FA: FactoryBase<'a, Ctx, Mtbl = Self::A> + InlineableFactory<'a, Ctx>;
/// Second element's factory. /// Second element's factory.
@ -110,7 +110,11 @@ impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> MentionableBase<'a, Ctx>
factory_data: self.pair.factory_data(), factory_data: self.pair.factory_data(),
} }
} }
}
impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> MentionableTop<'a, Ctx>
for StaticPairObject<SP>
{
fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) { fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) {
let (a, b) = self.pair.elements(); let (a, b) = self.pair.elements();
a.points_typed(points); a.points_typed(points);

View File

@ -43,7 +43,11 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableBase<'a, Ctx>
}, },
} }
} }
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableTop<'a, Ctx>
for Nullable<'a, Ctx, A>
{
fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) { fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) {
match self { match self {
Self::Null(_) => {} Self::Null(_) => {}

View File

@ -19,7 +19,9 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableBase<'a, Ctx> for
factory: self.origin.factory(), factory: self.origin.factory(),
} }
} }
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableTop<'a, Ctx> for Point<'a, Ctx, A> {
fn topology(&self) -> Hash { fn topology(&self) -> Hash {
Ctx::hash(&self.point) Ctx::hash(&self.point)
} }

View File

@ -54,7 +54,9 @@ impl<'a, Ctx: Context<'a>> MentionableBase<'a, Ctx> for TypelessMentionable<'a,
fn factory(&self) -> Self::Fctr { fn factory(&self) -> Self::Fctr {
self.t_factory.clone() self.t_factory.clone()
} }
}
impl<'a, Ctx: Context<'a>> MentionableTop<'a, Ctx> for TypelessMentionable<'a, Ctx> {
fn topology(&self) -> Hash { fn topology(&self) -> Hash {
self.t_topology self.t_topology
} }
@ -207,7 +209,7 @@ where
pub trait MentionableExt<'a, Ctx: Context<'a>>: Mentionable<'a, Ctx> { pub trait MentionableExt<'a, Ctx: Context<'a>>: Mentionable<'a, Ctx> {
/// References ([Point]s) to other objects. Typeless. /// References ([Point]s) to other objects. Typeless.
fn points_typeless(&self, points: &mut Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>); fn points_typeless(&self, points: &mut Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>);
/// [Vec] of [Point]s as used by [`MentionableBase::topology`]. /// [Vec] of [Point]s as used by [`MentionableTop::topology`].
fn points_vec(&self) -> Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>; fn points_vec(&self) -> Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>;
} }