diff --git a/src/rcore.rs b/src/rcore.rs
index bb43b31..0ce8b6b 100644
--- a/src/rcore.rs
+++ b/src/rcore.rs
@@ -49,9 +49,9 @@ pub use self::slice_deserializer::SliceDeserializer;
pub type Wrapped<'a, Ctx, A> = WrapC<'a, A, Ctx>;
/// Fundamental trait for ADN objects.
-pub trait Mentionable<'a, Ctx: Context<'a>>: 'a + Serializable {
+pub trait MentionableBase<'a, Ctx: Context<'a>>: 'a + Serializable + Sized {
/// Type of the associated factory.
- type Fctr: Factory<'a, Ctx, Mtbl = Self>;
+ type Fctr: FactoryBase<'a, Ctx, Mtbl = Self>;
/// Value of the associated factory.
fn factory(&self) -> Self::Fctr;
@@ -67,8 +67,19 @@ pub trait Mentionable<'a, Ctx: Context<'a>>: 'a + Serializable {
fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>);
}
+pub trait Mentionable<'a, Ctx: Context<'a>>: MentionableBase<'a, Ctx, Fctr = Self::_Fctr> {
+ type _Fctr: Factory<'a, Ctx, Mtbl = Self>;
+}
+
+impl<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> Mentionable<'a, Ctx> for A
+where
+ Self::Fctr: Factory<'a, Ctx>,
+{
+ type _Fctr = Self::Fctr;
+}
+
/// [`Factory`] associated with the [`Mentionable`]. Mostly useful for `type` definitions.
-pub type Fctr<'a, Ctx, A> = >::Fctr;
+pub type Fctr<'a, Ctx, A> = >::Fctr;
/// Shorthand for the type of vaalues returned by [`Factory::deserialize`].
pub type ParseResult<'a, Ctx, F> = Result, ParseError<'a, Ctx, F>>;
@@ -79,7 +90,7 @@ pub type ParseResultA<'a, Ctx, A> = Result>;
/// [Factory] base.
pub trait FactoryBase<'a, Ctx: Context<'a>>: 'a + Send + Sync + Clone {
/// Type of the associated objects.
- type Mtbl: Mentionable<'a, Ctx, Fctr = Self>;
+ type Mtbl: MentionableBase<'a, Ctx, Fctr = Self>;
/// Type of an error that [`Factory::deserialize`] can fail with.
type ParseError: 'a + Error;
}
diff --git a/src/rcore/modes.rs b/src/rcore/modes.rs
index f3a97e7..2a3eaad 100644
--- a/src/rcore/modes.rs
+++ b/src/rcore/modes.rs
@@ -6,25 +6,16 @@ pub trait ParseMode {
type Mode: ?Sized;
}
-pub struct RegularMode;
-
-pub trait RegularFactory<'a, Ctx: Context<'a>>:
- FactoryBase<'a, Ctx> + ParseMode
-{
- fn rdeserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self>;
- fn rextend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self>;
-}
-
pub trait WithParseMode: ParseMode {
type WithMode: ?Sized;
}
-pub struct WithMode(PhantomData, T);
-
impl WithParseMode for T {
type WithMode = WithMode::Mode>;
}
+pub struct WithMode(PhantomData, T);
+
pub trait FactoryProxy<'a, Ctx: Context<'a>> {
type F: FactoryBase<'a, Ctx> + ParseMode;
@@ -36,6 +27,28 @@ pub trait FactoryProxy<'a, Ctx: Context<'a>> {
) -> ParseResult<'a, Ctx, Self::F>;
}
+impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx> + WithParseMode> Factory<'a, Ctx> for F
+where
+ F::WithMode: FactoryProxy<'a, Ctx, F = Self>,
+{
+ fn deserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self> {
+ >::pdeserialize(self, inctx)
+ }
+
+ fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> {
+ >::pextend(self, mentionable, tail)
+ }
+}
+
+pub struct RegularMode;
+
+pub trait RegularFactory<'a, Ctx: Context<'a>>:
+ FactoryBase<'a, Ctx> + ParseMode
+{
+ fn rdeserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self>;
+ fn rextend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self>;
+}
+
impl<'a, Ctx: Context<'a>, F: RegularFactory<'a, Ctx>> FactoryProxy<'a, Ctx>
for WithMode
{
@@ -53,16 +66,3 @@ impl<'a, Ctx: Context<'a>, F: RegularFactory<'a, Ctx>> FactoryProxy<'a, Ctx>
f.rextend(mentionable, tail)
}
}
-
-impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx> + WithParseMode> Factory<'a, Ctx> for F
-where
- F::WithMode: FactoryProxy<'a, Ctx, F = Self>,
-{
- fn deserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self> {
- >::pdeserialize(self, inctx)
- }
-
- fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> {
- >::pextend(self, mentionable, tail)
- }
-}
diff --git a/src/rcore/origin.rs b/src/rcore/origin.rs
index 2817ee3..4dd8a1f 100644
--- a/src/rcore/origin.rs
+++ b/src/rcore/origin.rs
@@ -7,7 +7,9 @@ pub trait Origin<'a, Ctx: Context<'a>>: 'a {
/// Clone the associated factory.
fn factory(&self) -> OFctr<'a, Ctx, Self>;
/// Try resolving the value.
- fn resolve(self: Rc) -> Resolution<'a, Ctx, Self::Mtbl>;
+ fn resolve(self: Rc) -> Resolution<'a, Ctx, Self::Mtbl>
+ where
+ OFctr<'a, Ctx, Self>: Factory<'a, Ctx>;
/// Try resolving the bytes. Should avoid parsing the value.
fn resolve_bytes(self: Rc) -> HashResolution<'a, Ctx>;
}
diff --git a/src/rcore/point.rs b/src/rcore/point.rs
index f0bad20..648e94f 100644
--- a/src/rcore/point.rs
+++ b/src/rcore/point.rs
@@ -1,23 +1,23 @@
use super::*;
/// The main way to represent a reference in ADN.
-pub struct Point<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
+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 ([`Mentionable::topology`]).
+ /// and its topology ([`MentionableBase::topology`]).
pub point: Hash,
/// [Origin] used in [`Point::resolve`].
pub origin: Rc>,
}
-impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> PartialEq for Point<'a, Ctx, A> {
+impl<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> PartialEq for Point<'a, Ctx, A> {
/// Note: this doesn't check for [Factory] equality.
fn eq(&self, other: &Self) -> bool {
self.point == other.point
}
}
-impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Clone for Point<'a, Ctx, A> {
+impl<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> Clone for Point<'a, Ctx, A> {
fn clone(&self) -> Self {
Self {
point: self.point,
diff --git a/src/rcore/points.rs b/src/rcore/points.rs
index cc5108b..30b596d 100644
--- a/src/rcore/points.rs
+++ b/src/rcore/points.rs
@@ -1,13 +1,13 @@
use super::*;
-/// Visitor used in [`Mentionable::points_typed`].
+/// Visitor used in [`MentionableBase::points_typed`].
pub trait PointsVisitor<'a, Ctx: Context<'a>> {
/// Visit a [Point].
fn visit>(&mut self, point: &Point<'a, Ctx, A>);
}
impl<'a, Ctx: Context<'a>> PointsVisitor<'a, Ctx> for Vec {
- /// The only natural implementation, as used in [`Mentionable::topology`].
+ /// The only natural implementation, as used in [`MentionableBase::topology`].
fn visit>(&mut self, point: &Point<'a, Ctx, A>) {
self.extend(point.point)
}
diff --git a/src/rcore/resolution.rs b/src/rcore/resolution.rs
index a10d5e0..0fd0a15 100644
--- a/src/rcore/resolution.rs
+++ b/src/rcore/resolution.rs
@@ -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 [`Mentionable::points_typed()`].
+ /// Index of the point in the [`MentionableBase::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 ([`Mentionable::topology()`]) omitted.
+ /// with topology header ([`MentionableBase::topology()`]) omitted.
fn resolve(self: Rc, address: Address) -> HashResolution<'a, Ctx>;
}
diff --git a/src/rcore/resolver_origin.rs b/src/rcore/resolver_origin.rs
index 01460c6..4a88585 100644
--- a/src/rcore/resolver_origin.rs
+++ b/src/rcore/resolver_origin.rs
@@ -18,7 +18,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
}
}
-struct ResolverOrigin<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> {
+struct ResolverOrigin<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> {
r_factory: F,
r_address: Address,
r_resolver: Rc>,
@@ -47,7 +47,10 @@ impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Origin<'a, Ctx> for ResolverOrig
self.r_factory.clone()
}
- fn resolve(self: Rc) -> Resolution<'a, Ctx, Self::Mtbl> {
+ fn resolve(self: Rc) -> Resolution<'a, Ctx, Self::Mtbl>
+ where
+ OFctr<'a, Ctx, Self>: Factory<'a, Ctx>,
+ {
_resolve_origin(self)
}
diff --git a/src/rstd/atomic.rs b/src/rstd/atomic.rs
index 1d0555e..c6ad432 100644
--- a/src/rstd/atomic.rs
+++ b/src/rstd/atomic.rs
@@ -12,16 +12,16 @@ use std::marker::PhantomData;
use crate::rcore::*;
-pub use self::modes::{AtomicProxy, RegularAtomic};
-
use super::*;
+pub use self::modes::{AtomicProxy, RegularAtomic};
+
pub type AParseError = ::AParseError;
pub type AParseResult = Result>;
/// This trait combines functionality of [`Mentionable`] and [`Factory`],
-/// while limiting [`Mentionable::points_typed`] (and corresponding [`Mentionable::topology`])
+/// while limiting [`MentionableBase::points_typed`] (and corresponding [`MentionableBase::topology`])
/// to an empty sequence.
pub trait AtomicBase: 'static + Send + Sync + Send + Clone + Serializable {
/// Equivalent of [`FactoryBase::ParseError`].
diff --git a/src/rstd/atomic/array.rs b/src/rstd/atomic/array.rs
index 5046aca..3e68ce2 100644
--- a/src/rstd/atomic/array.rs
+++ b/src/rstd/atomic/array.rs
@@ -39,17 +39,7 @@ impl AtomicBase for [u8; N] {
}
impl ParseMode for [u8; N] {
- type Mode = RegularMode;
-}
-
-impl RegularAtomic for [u8; N] {
- fn ra_deserialize(inlining: impl Inlining) -> AParseResult {
- Self::a_ideserialize(inlining).seal()
- }
-
- fn ra_extend(self, tail: &[u8]) -> AParseResult {
- Err(Self::a_extension_error(tail))
- }
+ type Mode = InliningMode;
}
impl InlineableAtomic for [u8; N] {
diff --git a/src/rstd/atomic/atomic_object.rs b/src/rstd/atomic/atomic_object.rs
index 3f9b3ed..12c6b06 100644
--- a/src/rstd/atomic/atomic_object.rs
+++ b/src/rstd/atomic/atomic_object.rs
@@ -37,14 +37,15 @@ impl Serializable for AtomicObject {
}
pub trait AoProxy<'a, Ctx: Context<'a>>: AtomicProxy {
- type Mtbl: Mentionable<'a, Ctx, Fctr = Self::Fctr>;
+ type Mtbl: MentionableBase<'a, Ctx, Fctr = Self::Fctr>;
type Fctr: Factory<'a, Ctx, Mtbl = Self::Mtbl>;
fn factory() -> Self::Fctr;
fn wrap(a: Self::A) -> Self::Mtbl;
}
-impl<'a, Ctx: Context<'a>, A: AtomicBase + WithParseMode> Mentionable<'a, Ctx> for AtomicObject
+impl<'a, Ctx: Context<'a>, A: AtomicBase + WithParseMode> MentionableBase<'a, Ctx>
+ for AtomicObject
where
A::WithMode: AoProxy<'a, Ctx, Mtbl = Self, A = A>,
{
@@ -87,8 +88,8 @@ where
type ParseError = A::AParseError;
}
-impl ParseMode for AtomicFactory {
- type Mode = RegularMode;
+impl ParseMode for AtomicFactory {
+ type Mode = A::Mode;
}
impl<'a, Ctx: Context<'a>, A: RegularAtomic> AoProxy<'a, Ctx> for WithMode {
diff --git a/src/rstd/atomic/au64.rs b/src/rstd/atomic/au64.rs
index b4917d4..309fc2d 100644
--- a/src/rstd/atomic/au64.rs
+++ b/src/rstd/atomic/au64.rs
@@ -39,17 +39,7 @@ impl AtomicBase for u64 {
}
impl ParseMode for u64 {
- type Mode = RegularMode;
-}
-
-impl RegularAtomic for u64 {
- fn ra_deserialize(inlining: impl Inlining) -> AParseResult {
- Self::a_ideserialize(inlining).seal()
- }
-
- fn ra_extend(self, tail: &[u8]) -> AParseResult {
- Err(Self::a_extension_error(tail))
- }
+ type Mode = InliningMode;
}
impl InlineableAtomic for u64 {
diff --git a/src/rstd/atomic/boolean.rs b/src/rstd/atomic/boolean.rs
index b873a08..7c30eb4 100644
--- a/src/rstd/atomic/boolean.rs
+++ b/src/rstd/atomic/boolean.rs
@@ -46,17 +46,7 @@ impl AtomicBase for bool {
}
impl ParseMode for bool {
- type Mode = RegularMode;
-}
-
-impl RegularAtomic for bool {
- fn ra_deserialize(inlining: impl Inlining) -> AParseResult {
- Self::a_ideserialize(inlining).seal()
- }
-
- fn ra_extend(self, tail: &[u8]) -> AParseResult {
- Err(Self::a_extension_error(tail))
- }
+ type Mode = InliningMode;
}
impl InlineableAtomic for bool {
diff --git a/src/rstd/atomic/modes.rs b/src/rstd/atomic/modes.rs
index f58d6ba..50f8b83 100644
--- a/src/rstd/atomic/modes.rs
+++ b/src/rstd/atomic/modes.rs
@@ -1,10 +1,5 @@
use super::*;
-pub trait RegularAtomic: AtomicBase + ParseMode {
- fn ra_deserialize(inlining: impl Inlining) -> AParseResult;
- fn ra_extend(self, tail: &[u8]) -> AParseResult;
-}
-
pub trait AtomicProxy {
type A: AtomicBase + ParseMode;
@@ -12,18 +7,6 @@ pub trait AtomicProxy {
fn pa_extend(a: Self::A, tail: &[u8]) -> AParseResult;
}
-impl AtomicProxy for WithMode {
- type A = A;
-
- fn pa_deserialize(inlining: impl Inlining) -> AParseResult {
- A::ra_deserialize(inlining)
- }
-
- fn pa_extend(a: Self::A, tail: &[u8]) -> AParseResult {
- a.ra_extend(tail)
- }
-}
-
impl Atomic for A
where
A::WithMode: AtomicProxy,
@@ -36,3 +19,20 @@ where
::pa_extend(self, tail)
}
}
+
+pub trait RegularAtomic: AtomicBase + ParseMode {
+ fn ra_deserialize(inlining: impl Inlining) -> AParseResult;
+ fn ra_extend(self, tail: &[u8]) -> AParseResult;
+}
+
+impl AtomicProxy for WithMode {
+ type A = A;
+
+ fn pa_deserialize(inlining: impl Inlining) -> AParseResult {
+ A::ra_deserialize(inlining)
+ }
+
+ fn pa_extend(a: Self::A, tail: &[u8]) -> AParseResult {
+ a.ra_extend(tail)
+ }
+}
diff --git a/src/rstd/cast.rs b/src/rstd/cast.rs
index 44d0107..26ac748 100644
--- a/src/rstd/cast.rs
+++ b/src/rstd/cast.rs
@@ -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 [`Mentionable::points_typed`] and/or [`Mentionable::topology`].
+ /// of [`MentionableBase::points_typed`] and/or [`MentionableBase::topology`].
AddressIndexOutOfBounds {
index: usize,
length: usize,
diff --git a/src/rstd/collections/stack.rs b/src/rstd/collections/stack.rs
index add0670..0284e37 100644
--- a/src/rstd/collections/stack.rs
+++ b/src/rstd/collections/stack.rs
@@ -5,7 +5,7 @@ use crate::rcore::*;
use crate::rstd::{inlining::*, nullable::*, point::*, *};
/// Node containing a (nullable) reference to the next node and an element.
-pub struct StackNode<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
+pub struct StackNode<'a, Ctx: Context<'a>, A: StackCompatible<'a, Ctx>> {
/// Reference comes first due to being inlineable.
pub rest: Stack<'a, Ctx, A>,
/// Unlike the original implementation in Python, doesn't default to using Point.
@@ -28,14 +28,59 @@ impl StackNodeFactory {
}
}
-impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Serializable for StackNode<'a, Ctx, A> {
+impl<'a, Ctx: Context<'a>, A: StackCompatible<'a, Ctx>> Serializable for StackNode<'a, Ctx, A> {
fn serialize(&self, serializer: &mut dyn Serializer) {
self.rest.serialize(serializer);
self.element.serialize(serializer);
}
}
-impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for StackNode<'a, Ctx, A> {
+pub trait StackCompatible<'a, Ctx: Context<'a>>: Mentionable<'a, Ctx> {
+ fn points_typed_rest(stack: &Stack<'a, Ctx, Self>, points: &mut impl PointsVisitor<'a, Ctx>);
+}
+
+pub trait StackCompatibleProxy<'a, Ctx: Context<'a>, T>: FactoryProxy<'a, Ctx>
+where
+ Self::F: Factory<'a, Ctx>,
+{
+ fn points_typed_rest(stack: &T, points: &mut impl PointsVisitor<'a, Ctx>);
+}
+
+impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> StackCompatible<'a, Ctx> for A
+where
+ as WithParseMode>::WithMode:
+ StackCompatibleProxy<'a, Ctx, Stack<'a, Ctx, A>, F = Fctr<'a, Ctx, A>>,
+{
+ fn points_typed_rest(stack: &Stack<'a, Ctx, Self>, points: &mut impl PointsVisitor<'a, Ctx>) {
+ < as WithParseMode>::WithMode as StackCompatibleProxy<'a, Ctx, _>>::points_typed_rest(stack, points)
+ }
+}
+
+impl<'a, Ctx: Context<'a>, F: RegularFactory<'a, Ctx>>
+ StackCompatibleProxy<'a, Ctx, Stack<'a, Ctx, Mtbl<'a, Ctx, F>>> for WithMode
+{
+ fn points_typed_rest(
+ stack: &Stack<'a, Ctx, Mtbl<'a, Ctx, Self::F>>,
+ points: &mut impl PointsVisitor<'a, Ctx>,
+ ) {
+ stack.points_typed(points)
+ }
+}
+
+impl<'a, Ctx: Context<'a>, F: InlineableFactory<'a, Ctx>>
+ StackCompatibleProxy<'a, Ctx, Stack<'a, Ctx, Mtbl<'a, Ctx, F>>> for WithMode
+{
+ fn points_typed_rest(
+ stack: &Stack<'a, Ctx, Mtbl<'a, Ctx, Self::F>>,
+ points: &mut impl PointsVisitor<'a, Ctx>,
+ ) {
+ stack.points_typed(points)
+ }
+}
+
+impl<'a, Ctx: Context<'a>, A: StackCompatible<'a, Ctx>> MentionableBase<'a, Ctx>
+ for StackNode<'a, Ctx, A>
+{
type Fctr = StackNodeFactory;
fn factory(&self) -> Self::Fctr {
@@ -43,7 +88,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Sta
}
fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) {
- self.rest.points_typed(points);
+ >::points_typed_rest(&self.rest, points);
self.element.points_typed(points);
}
}
@@ -81,23 +126,28 @@ impl StackNodeFactory {
inctx: I,
) -> IParseResult<'a, Ctx, NullableFactory, I>
where
- F: FactoryBase<'a, Ctx>,
+ StackNodeFactory: Factory<'a, Ctx>,
{
NullableFactory::new(self.clone()).ideserialize(inctx)
}
}
-impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> FactoryBase<'a, Ctx> for StackNodeFactory {
+impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> FactoryBase<'a, Ctx> for StackNodeFactory
+where
+ F::Mtbl: StackCompatible<'a, Ctx, _Fctr = F>,
+{
type Mtbl = StackNode<'a, Ctx, F::Mtbl>;
type ParseError = StackParseError>;
}
-impl ParseMode for StackNodeFactory {
- type Mode = RegularMode;
+impl ParseMode for StackNodeFactory {
+ type Mode = F::Mode;
}
-impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> RegularFactory<'a, Ctx> for StackNodeFactory {
+impl<'a, Ctx: Context<'a>, F: RegularFactory<'a, Ctx>> RegularFactory<'a, Ctx>
+ for StackNodeFactory
+{
fn rdeserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self> {
let (rest, inctx) = self.parse_point(inctx)?;
let element = self
@@ -126,7 +176,9 @@ pub type StackVecResult<'a, Ctx, A> = Result, StackFaiure<'a, Ctx, A>>;
pub type StackVecWrapped<'a, Ctx, A> = Wrapped<'a, Ctx, StackVecResult<'a, Ctx, A>>;
/// Extention trait with helper methods for [Stack]s.
-pub trait ExtStack<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>>: Mentionable<'a, Ctx> {
+pub trait ExtStack<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>>:
+ MentionableBase<'a, Ctx>
+{
/// Get an empty stack ([`Nullable::Null`]).
fn empty(factory: A::Fctr) -> Self;
/// Get the corresponding factory.
@@ -138,14 +190,17 @@ pub trait ExtStack<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>>: Mentionable<'
}
/// Extention trait with helper methods for [Stack]s.
-pub trait ExtStackClone<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone>:
- Mentionable<'a, Ctx>
+pub trait ExtStackClone<'a, Ctx: Context<'a>, A: StackCompatible<'a, Ctx> + Clone>:
+ MentionableBase<'a, Ctx>
{
/// Collect all the elements into a [`Vec`].
fn vec(self) -> StackVecWrapped<'a, Ctx, A>;
}
-impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> ExtStack<'a, Ctx, A> for Stack<'a, Ctx, A> {
+impl<'a, Ctx: Context<'a>, A: StackCompatible<'a, Ctx>> ExtStack<'a, Ctx, A> for Stack<'a, Ctx, A>
+where
+ Fctr<'a, Ctx, StackNode<'a, Ctx, A>>: Factory<'a, Ctx>,
+{
fn empty(factory: A::Fctr) -> Self {
Nullable::Null(StackNodeFactory::new(factory.clone()))
}
@@ -163,8 +218,10 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> ExtStack<'a, Ctx, A> for Sta
}
}
-impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone> ExtStackClone<'a, Ctx, A>
+impl<'a, Ctx: Context<'a>, A: StackCompatible<'a, Ctx> + Clone> ExtStackClone<'a, Ctx, A>
for Stack<'a, Ctx, A>
+where
+ Fctr<'a, Ctx, StackNode<'a, Ctx, A>>: Factory<'a, Ctx>,
{
fn vec(self) -> StackVecWrapped<'a, Ctx, A> {
Ctx::T::iterate_mut((vec![], self), |(mut vec, stack)| match stack {
diff --git a/src/rstd/collections/tree.rs b/src/rstd/collections/tree.rs
index 618e50a..338372b 100644
--- a/src/rstd/collections/tree.rs
+++ b/src/rstd/collections/tree.rs
@@ -5,12 +5,7 @@ use std::{error::Error, fmt::Display};
use crate::{
flow::binary::*,
rcore::*,
- rstd::{
- atomic::{au64::*, *},
- inlining::*,
- nullable::*,
- point::*,
- },
+ rstd::{atomic::au64::*, inlining::*, nullable::*, point::*},
};
#[derive(Debug)]
@@ -105,7 +100,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Serializable for Tree<'a, Ct
}
}
-impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Node<'a, Ctx, A> {
+impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableBase<'a, Ctx> for Node<'a, Ctx, A> {
type Fctr = NodeFactory;
fn factory(&self) -> Self::Fctr {
@@ -119,7 +114,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Nod
}
}
-impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Tree<'a, Ctx, A> {
+impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableBase<'a, Ctx> for Tree<'a, Ctx, A> {
type Fctr = TreeFactory;
fn factory(&self) -> Self::Fctr {
@@ -131,7 +126,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Tre
}
}
-impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> FactoryBase<'a, Ctx> for NodeFactory {
+impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> FactoryBase<'a, Ctx> for NodeFactory {
type Mtbl = Node<'a, Ctx, F::Mtbl>;
type ParseError = TreeParseError;
@@ -159,29 +154,17 @@ impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> RegularFactory<'a, Ctx> for Node
}
}
-impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> FactoryBase<'a, Ctx> for TreeFactory {
+impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> FactoryBase<'a, Ctx> for TreeFactory {
type Mtbl = Tree<'a, Ctx, F::Mtbl>;
type ParseError = TreeParseError;
}
impl ParseMode for TreeFactory {
- type Mode = RegularMode;
+ type Mode = InliningMode;
}
-impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> RegularFactory<'a, Ctx> for TreeFactory {
- fn rdeserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self> {
- self.ideserialize(inctx).seal()
- }
-
- fn rextend(&self, mut mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> {
- mentionable.height = u64::a_extend(mentionable.height, tail)?;
- mentionable.validate_height()?;
- Ok(mentionable)
- }
-}
-
-impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> InlineableFactory<'a, Ctx> for TreeFactory {
+impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> InlineableFactory<'a, Ctx> for TreeFactory {
fn extension_error(&self, tail: &[u8]) -> Self::ParseError {
u64::a_extension_error(tail).into()
}
diff --git a/src/rstd/inlining.rs b/src/rstd/inlining.rs
index c748dd5..adab0a5 100644
--- a/src/rstd/inlining.rs
+++ b/src/rstd/inlining.rs
@@ -1,5 +1,6 @@
//! Traits to better express parsing semantics.
+mod modes;
pub mod static_pair;
use crate::rcore::*;
@@ -9,10 +10,14 @@ use super::{
*,
};
+pub use self::modes::InliningMode;
+
pub type IParseResult<'a, Ctx, F, I> = Result<(Mtbl<'a, Ctx, F>, I), ParseError<'a, Ctx, F>>;
/// This factory should return an error on EOF.
-pub trait InlineableFactory<'a, Ctx: Context<'a>>: FactoryBase<'a, Ctx> {
+pub trait InlineableFactory<'a, Ctx: Context<'a>>:
+ FactoryBase<'a, Ctx> + ParseMode
+{
fn extension_error(&self, tail: &[u8]) -> Self::ParseError;
fn ideserialize>(&self, inctx: I) -> IParseResult<'a, Ctx, Self, I>;
@@ -48,7 +53,7 @@ pub trait ConstSizeObject<'a, Ctx: Context<'a>>: FixedSizeObject<'a, Ctx> {
pub type ADParseResult = Result<(A, D), AParseError>;
/// Atomic analogue of [`InlineableFactory`]/[`InlineableObject`].
-pub trait InlineableAtomic: AtomicBase + ParseMode {
+pub trait InlineableAtomic: AtomicBase + ParseMode {
fn a_extension_error(tail: &[u8]) -> Self::AParseError;
fn a_ideserialize(inlining: D) -> ADParseResult;
diff --git a/src/rstd/inlining/modes.rs b/src/rstd/inlining/modes.rs
new file mode 100644
index 0000000..decb4ac
--- /dev/null
+++ b/src/rstd/inlining/modes.rs
@@ -0,0 +1,33 @@
+use super::*;
+
+pub struct InliningMode;
+
+impl<'a, Ctx: Context<'a>, F: InlineableFactory<'a, Ctx>> FactoryProxy<'a, Ctx>
+ for WithMode
+{
+ type F = F;
+
+ fn pdeserialize(f: &Self::F, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self::F> {
+ f.ideserialize(inctx).seal()
+ }
+
+ fn pextend(
+ f: &Self::F,
+ _mentionable: Mtbl<'a, Ctx, Self::F>,
+ tail: &[u8],
+ ) -> ParseResult<'a, Ctx, Self::F> {
+ Err(f.extension_error(tail))
+ }
+}
+
+impl AtomicProxy for WithMode {
+ type A = A;
+
+ fn pa_deserialize(inlining: impl Inlining) -> AParseResult {
+ A::a_ideserialize(inlining).seal()
+ }
+
+ fn pa_extend(_a: Self::A, tail: &[u8]) -> AParseResult {
+ Err(A::a_extension_error(tail))
+ }
+}
diff --git a/src/rstd/inlining/static_pair.rs b/src/rstd/inlining/static_pair.rs
index cf89c63..171a68d 100644
--- a/src/rstd/inlining/static_pair.rs
+++ b/src/rstd/inlining/static_pair.rs
@@ -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: Mentionable<'a, Ctx, Fctr = Self::FA>;
+ type A: MentionableBase<'a, Ctx, Fctr = Self::FA>;
/// Second element's type. Must equal [`StaticPairSerializable::SB`].
- type B: Mentionable<'a, Ctx, Fctr = Self::FB>;
+ type B: MentionableBase<'a, Ctx, Fctr = Self::FB>;
/// First element's factory.
type FA: Factory<'a, Ctx, Mtbl = Self::A> + InlineableFactory<'a, Ctx>;
/// Second element's factory.
@@ -100,7 +100,9 @@ impl Serializable for StaticPairObject {
}
}
-impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> Mentionable<'a, Ctx> for StaticPairObject {
+impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> MentionableBase<'a, Ctx>
+ for StaticPairObject
+{
type Fctr = StaticPairFactory<'a, Ctx, SP>;
fn factory(&self) -> Self::Fctr {
@@ -133,11 +135,13 @@ impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> FactoryBase<'a, Ctx>
}
impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> ParseMode for StaticPairFactory<'a, Ctx, SP> {
- type Mode = RegularMode;
+ type Mode = ::Mode;
}
impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> RegularFactory<'a, Ctx>
for StaticPairFactory<'a, Ctx, SP>
+where
+ SP::FB: RegularFactory<'a, Ctx>,
{
fn rdeserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self> {
let (fa, fb) = SP::factories(&self.factory_data);
diff --git a/src/rstd/nullable.rs b/src/rstd/nullable.rs
index 438a614..7e08dca 100644
--- a/src/rstd/nullable.rs
+++ b/src/rstd/nullable.rs
@@ -6,7 +6,7 @@ use crate::rcore::*;
use super::{inlining::*, point::*, *};
/// Nullable reference type. Made for use as a linking element in data structures.
-pub enum Nullable<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
+pub enum Nullable<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> {
/// Unlike original Python implementation, stores the factory only in the null case.
Null(A::Fctr),
NotNull(Point<'a, Ctx, A>),
@@ -19,7 +19,7 @@ pub struct NullableFactory {
factory: F,
}
-impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Serializable for Nullable<'a, Ctx, A> {
+impl<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> Serializable for Nullable<'a, Ctx, A> {
fn serialize(&self, serializer: &mut dyn Serializer) {
serializer.write(match self {
Self::Null(_) => &HASH_ZEROS,
@@ -28,7 +28,9 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Serializable for Nullable<'a
}
}
-impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Nullable<'a, Ctx, A> {
+impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableBase<'a, Ctx>
+ for Nullable<'a, Ctx, A>
+{
type Fctr = NullableFactory;
fn factory(&self) -> Self::Fctr {
@@ -50,24 +52,14 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Nul
}
}
-impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> FactoryBase<'a, Ctx> for NullableFactory {
+impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> FactoryBase<'a, Ctx> for NullableFactory {
type Mtbl = Nullable<'a, Ctx, F::Mtbl>;
type ParseError = PointParseError;
}
impl ParseMode for NullableFactory {
- type Mode = RegularMode;
-}
-
-impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> RegularFactory<'a, Ctx> for NullableFactory {
- fn rdeserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self> {
- self.ideserialize(inctx).seal()
- }
-
- fn rextend(&self, _mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> {
- Err(self.extension_error(tail))
- }
+ type Mode = InliningMode;
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Nullable<'a, Ctx, Nullable<'a, Ctx, A>> {
@@ -102,7 +94,7 @@ impl NullableFactory {
}
}
-impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Clone for Nullable<'a, Ctx, A> {
+impl<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> Clone for Nullable<'a, Ctx, A> {
fn clone(&self) -> Self {
match self {
Self::Null(factory) => Self::Null(factory.clone()),
@@ -111,9 +103,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Clone for Nullable<'a, Ctx,
}
}
-impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> InlineableFactory<'a, Ctx>
- for NullableFactory
-{
+impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> InlineableFactory<'a, Ctx> for NullableFactory {
fn extension_error(&self, tail: &[u8]) -> Self::ParseError {
PointParseError::WrongLength(HASH_SIZE + tail.len())
}
diff --git a/src/rstd/point.rs b/src/rstd/point.rs
index 524805d..2f3f7ee 100644
--- a/src/rstd/point.rs
+++ b/src/rstd/point.rs
@@ -11,7 +11,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Serializable for Point<'a, C
}
}
-impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Point<'a, Ctx, A> {
+impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableBase<'a, Ctx> for Point<'a, Ctx, A> {
type Fctr = PointFactory;
fn factory(&self) -> Self::Fctr {
@@ -69,27 +69,17 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> AsRef<[u8]> for Point<'a, Ct
}
}
-impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> FactoryBase<'a, Ctx> for PointFactory {
+impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> FactoryBase<'a, Ctx> for PointFactory {
type Mtbl = Point<'a, Ctx, F::Mtbl>;
type ParseError = PointParseError;
}
impl ParseMode for PointFactory {
- type Mode = RegularMode;
+ type Mode = InliningMode;
}
-impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> RegularFactory<'a, Ctx> for PointFactory {
- fn rdeserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Ctx, Self> {
- self.ideserialize(inctx).seal()
- }
-
- fn rextend(&self, _mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> {
- Err(self.extension_error(tail))
- }
-}
-
-impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> InlineableFactory<'a, Ctx> for PointFactory {
+impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> InlineableFactory<'a, Ctx> for PointFactory {
fn extension_error(&self, tail: &[u8]) -> Self::ParseError {
PointParseError::WrongLength(HASH_SIZE + tail.len())
}
diff --git a/src/rstd/typeless.rs b/src/rstd/typeless.rs
index 72a163e..aadd518 100644
--- a/src/rstd/typeless.rs
+++ b/src/rstd/typeless.rs
@@ -48,7 +48,7 @@ impl<'a, Ctx: Context<'a>> Serializable for TypelessMentionable<'a, Ctx> {
}
}
-impl<'a, Ctx: Context<'a>> Mentionable<'a, Ctx> for TypelessMentionable<'a, Ctx> {
+impl<'a, Ctx: Context<'a>> MentionableBase<'a, Ctx> for TypelessMentionable<'a, Ctx> {
type Fctr = TypelessFactory<'a, Ctx>;
fn factory(&self) -> Self::Fctr {
@@ -207,7 +207,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>>);
- /// [Vec] of [Point]s as used by [`Mentionable::topology`].
+ /// [Vec] of [Point]s as used by [`MentionableBase::topology`].
fn points_vec(&self) -> Vec>>;
}