MentionableTop
This commit is contained in:
parent
7ebc5ba615
commit
c6b3029798
12
src/rcore.rs
12
src/rcore.rs
@ -55,6 +55,9 @@ pub trait MentionableBase<'a, Ctx: Context<'a>>: 'a + Serializable + Sized {
|
||||
|
||||
/// Value of the associated factory.
|
||||
fn factory(&self) -> Self::Fctr;
|
||||
}
|
||||
|
||||
pub trait MentionableTop<'a, Ctx: Context<'a>>: 'a {
|
||||
/// See implementation for the definition.
|
||||
/// 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.
|
||||
@ -67,11 +70,14 @@ pub trait MentionableBase<'a, Ctx: Context<'a>>: 'a + Serializable + Sized {
|
||||
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>;
|
||||
}
|
||||
|
||||
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
|
||||
Self::Fctr: Factory<'a, Ctx>,
|
||||
{
|
||||
@ -90,7 +96,7 @@ pub type ParseResultA<'a, Ctx, A> = Result<A, ParseErrorA<'a, Ctx, A>>;
|
||||
/// [Factory] base.
|
||||
pub trait FactoryBase<'a, Ctx: Context<'a>>: 'a + Send + Sync + Clone {
|
||||
/// 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 ParseError: 'a + Error;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use super::*;
|
||||
/// Represents a potentially resolvable [`Mentionable`].
|
||||
pub trait Origin<'a, Ctx: Context<'a>>: 'a {
|
||||
/// Type of the associated object.
|
||||
type Mtbl: MentionableBase<'a, Ctx>;
|
||||
type Mtbl: MentionableBase<'a, Ctx> + MentionableTop<'a, Ctx>;
|
||||
/// Clone the associated factory.
|
||||
fn factory(&self) -> OFctr<'a, Ctx, Self>;
|
||||
/// Try resolving the value.
|
||||
|
@ -4,7 +4,7 @@ use super::*;
|
||||
pub struct Point<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> {
|
||||
/// Hash of the referred content.
|
||||
/// Derived both from the serialised value ([`Serializable::serialize`])
|
||||
/// and its topology ([`MentionableBase::topology`]).
|
||||
/// and its topology ([`MentionableTop::topology`]).
|
||||
pub point: Hash,
|
||||
/// [Origin] used in [`Point::resolve`].
|
||||
pub origin: Rc<dyn Origin<'a, Ctx, Mtbl = A>>,
|
||||
|
@ -1,13 +1,13 @@
|
||||
use super::*;
|
||||
|
||||
/// Visitor used in [`MentionableBase::points_typed`].
|
||||
/// Visitor used in [`MentionableTop::points_typed`].
|
||||
pub trait PointsVisitor<'a, Ctx: Context<'a>> {
|
||||
/// Visit a [Point].
|
||||
fn visit<A: Mentionable<'a, Ctx>>(&mut self, point: &Point<'a, Ctx, A>);
|
||||
}
|
||||
|
||||
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>) {
|
||||
self.extend(point.point)
|
||||
}
|
||||
|
@ -44,14 +44,14 @@ pub type HashResolution<'a, Ctx> = Wrapped<'a, Ctx, HashResolutionResult<'a, Ctx
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Address {
|
||||
pub point: Hash,
|
||||
/// Index of the point in the [`MentionableBase::points_typed()`].
|
||||
/// Index of the point in the [`MentionableTop::points_typed()`].
|
||||
pub index: usize,
|
||||
}
|
||||
|
||||
/// Trait representing the "rainbow table" behaviour.
|
||||
pub trait Resolver<'a, Ctx: Context<'a>>: 'a {
|
||||
/// 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>;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ pub type AParseError<A> = <A as AtomicBase>::AParseError;
|
||||
pub type AParseResult<A> = Result<A, AParseError<A>>;
|
||||
|
||||
/// 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.
|
||||
pub trait AtomicBase: 'static + Send + Sync + Send + Clone + Serializable {
|
||||
/// Equivalent of [`FactoryBase::ParseError`].
|
||||
|
@ -37,7 +37,7 @@ impl<A: AtomicBase> Serializable for AtomicObject<A> {
|
||||
}
|
||||
|
||||
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>;
|
||||
|
||||
fn factory() -> Self::Fctr;
|
||||
@ -54,7 +54,9 @@ where
|
||||
fn factory(&self) -> Self::Fctr {
|
||||
<A::WithMode as AoProxy<'a, Ctx>>::factory()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: Context<'a>, A: AtomicBase> MentionableTop<'a, Ctx> for AtomicObject<A> {
|
||||
fn topology(&self) -> Hash {
|
||||
Ctx::hash(b"")
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ pub enum CastError<'a> {
|
||||
/// 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.
|
||||
/// This error usually indicates inconsistent behaviour
|
||||
/// of [`MentionableBase::points_typed`] and/or [`MentionableBase::topology`].
|
||||
/// of [`MentionableTop::points_typed`] and/or [`MentionableTop::topology`].
|
||||
AddressIndexOutOfBounds {
|
||||
index: usize,
|
||||
length: usize,
|
||||
|
@ -86,7 +86,11 @@ impl<'a, Ctx: Context<'a>, A: StackCompatible<'a, Ctx>> MentionableBase<'a, Ctx>
|
||||
fn factory(&self) -> Self::Fctr {
|
||||
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>) {
|
||||
<A as StackCompatible<'a, Ctx>>::points_typed_rest(&self.rest, points);
|
||||
self.element.points_typed(points);
|
||||
|
@ -106,7 +106,9 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableBase<'a, Ctx> for
|
||||
fn factory(&self) -> Self::Fctr {
|
||||
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>) {
|
||||
self.l.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 {
|
||||
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>) {
|
||||
self.node.points_typed(points);
|
||||
}
|
||||
|
@ -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).
|
||||
type FactoryData: 'a + Send + Sync + Clone;
|
||||
/// 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`].
|
||||
type B: MentionableBase<'a, Ctx, Fctr = Self::FB>;
|
||||
type B: MentionableBase<'a, Ctx, Fctr = Self::FB> + MentionableTop<'a, Ctx>;
|
||||
/// First element's factory.
|
||||
type FA: FactoryBase<'a, Ctx, Mtbl = Self::A> + InlineableFactory<'a, Ctx>;
|
||||
/// 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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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>) {
|
||||
let (a, b) = self.pair.elements();
|
||||
a.points_typed(points);
|
||||
|
@ -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>) {
|
||||
match self {
|
||||
Self::Null(_) => {}
|
||||
|
@ -19,7 +19,9 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableBase<'a, Ctx> for
|
||||
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 {
|
||||
Ctx::hash(&self.point)
|
||||
}
|
||||
|
@ -54,7 +54,9 @@ impl<'a, Ctx: Context<'a>> MentionableBase<'a, Ctx> for TypelessMentionable<'a,
|
||||
fn factory(&self) -> Self::Fctr {
|
||||
self.t_factory.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: Context<'a>> MentionableTop<'a, Ctx> for TypelessMentionable<'a, Ctx> {
|
||||
fn topology(&self) -> Hash {
|
||||
self.t_topology
|
||||
}
|
||||
@ -207,7 +209,7 @@ where
|
||||
pub trait MentionableExt<'a, Ctx: Context<'a>>: Mentionable<'a, Ctx> {
|
||||
/// References ([Point]s) to other objects. Typeless.
|
||||
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>>>;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user