1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! Core module for ADN functionality.
//! Brings [`Mentionable`]/[`Factory`]/[`Origin`] concepts from the original implementation in Python.
//! Allows for more generic behaviour via [`Context`], as opposed to original async-only.

use std::{error::Error, sync::Arc};

use crate::func::context::*;
use crate::mode::*;

pub use self::context::Context;
pub use self::demoted::Demoted;
pub use self::diagnostic::Diagnostic;
pub use self::hashing::{Hash, HASH_SIZE, HASH_ZEROS};
pub use self::inctx::InCtx;
pub use self::inlining::{CInliningFactory, IParseResult, InliningFactory};
pub use self::modes::{
    ExtensionResultM, ExtensionSourceM, FactoryModeParse, FactoryModeProxy, ModeResultM,
};
pub use self::origin::{OFctr, Origin, OriginMap};
pub use self::point::Point;
pub use self::points::PointsVisitor;
pub use self::regular::{CRegularFactory, RegularFactory};
pub use self::resolution::{
    Address, HashResolution, HashResolutionResult, LookupError, Resolution, ResolutionError,
    ResolutionFailure, ResolutionResult, Resolver, ResolverMap,
};
pub use self::singular::{SingularError, SingularResolution};
pub use self::to_hex::hex;
pub use self::topology::{MentionableTop, TopoVec, Topology};

mod addresses;
mod context;
mod dectx;
mod demoted;
mod diagnostic;
mod hashing;
mod inctx;
mod inlining;
mod modes;
mod origin;
mod point;
mod points;
mod regular;
mod resolution;
mod resolver_origin;
mod singular;
mod to_hex;
mod topology;

/// Helper alias for [`WeakFunctor::F`] of [`FunctorContext::T`].
///
/// [`WeakFunctor::F`]: crate::func::WeakFunctor::F
pub type Wrapped<'a, Ctx, A> = WrapC<'a, A, Ctx>;

/// [Mentionable] base.
pub trait MentionableBase<'a>: 'a + Send + Sync + Serializable + Sized {
    /// Type of the associated factory.
    type Fctr: FactoryBase<'a, Mtbl = Self>;

    /// Value of the associated factory.
    fn factory(&self) -> Self::Fctr;
}

/// Fundamental trait for ADN objects.
pub trait Mentionable<'a, Ctx: Context<'a>>:
    MentionableBase<'a, Fctr = Self::_Fctr> + MentionableTop<'a, Ctx>
{
    type _Fctr: Factory<'a, Ctx, _Mtbl = Self>;
}

impl<'a, Ctx: Context<'a>, A: MentionableBase<'a> + MentionableTop<'a, Ctx>> Mentionable<'a, Ctx>
    for A
where
    Self::Fctr: Factory<'a, Ctx, _Mtbl = Self>,
{
    type _Fctr = Self::Fctr;
}

/// [`Factory`] associated with the [`Mentionable`]. Mostly useful for `type` definitions.
pub type Fctr<'a, A> = <A as MentionableBase<'a>>::Fctr;

/// Shorthand for the type of values returned by [`FactoryParse::deserialize`].
pub type ParseResult<'a, F> = Result<Mtbl<'a, F>, ParseError<'a, F>>;

/// [`ParseResult`] associated with a [`Mentionable`] (instead of a [`Factory`]).
pub type ParseResultA<'a, A> = Result<A, ParseErrorA<'a, A>>;

/// [Factory] base.
pub trait FactoryBase<'a>: 'a + Send + Sync + Clone {
    /// Type of the associated objects.
    type Mtbl: MentionableBase<'a, Fctr = Self>;
    /// Type of an error that [`FactoryParse::deserialize`] can fail with.
    type ParseError: 'a + Send + Error;
}

/// [Factory] that allows parsing consuming the parser.
pub trait FactoryParse<'a, Ctx: Context<'a>>: FactoryModeParse<'a, Ctx> {
    /// Consumes the parser. See [`Deserializer`], [`Resolver`].
    fn deserialize(&self, inctx: impl InCtx<'a, Ctx>) -> ParseResult<'a, Self>;
    /// Called by finite stream parsers if there's any data left.
    fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Self>;
}

/// Trait representing deserialisation rules for [Mentionable]s.
/// Crucial for [typeless]ness.
///
/// [typeless]: crate::rstd::typeless
pub trait Factory<'a, Ctx: Context<'a>>:
    FactoryParse<'a, Ctx, Mtbl = Self::_Mtbl> + ParseMode
{
    type _Mtbl: MentionableBase<'a, Fctr = Self> + MentionableTop<'a, Ctx>;
}

impl<'a, Ctx: Context<'a>, F: FactoryParse<'a, Ctx> + ParseMode> Factory<'a, Ctx> for F
where
    F::Mtbl: MentionableTop<'a, Ctx>,
{
    type _Mtbl = Self::Mtbl;
}

/// [`Mentionable`] associated with the [`Factory`]. Mostly useful for `type` definitions.
pub type Mtbl<'a, F> = <F as FactoryBase<'a>>::Mtbl;

/// [`FactoryBase::ParseError`]. Mostly useful for `type` definitions.
pub type ParseError<'a, F> = <F as FactoryBase<'a>>::ParseError;

/// [`FactoryBase::ParseError`] associated with the [`Mentionable`].
/// Mostly useful for `type` definitions.
pub type ParseErrorA<'a, A> = ParseError<'a, Fctr<'a, A>>;

/// Extension trait for factories.
pub trait FactoryExt<'a, Ctx: Context<'a>>: FactoryParse<'a, Ctx> {
    /// Parse the object from a slice.
    fn parse_slice(
        &self,
        slice: &[u8],
        resolver: &Arc<dyn Resolver<'a, Ctx>>,
    ) -> ParseResult<'a, Self>;
}