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
use super::*;

impl<A: AtomicModeParse> Atomic for A {
    fn a_deserialize(stream: impl Stream) -> AParseResult<Self> {
        Self::ma_deserialize(stream).map(Self::seal)
    }

    fn a_extend(self, tail: &[u8]) -> AParseResult<Self> {
        Self::xseal(Self::ma_extend(Self::prepare(self), tail))
    }
}

/// [`Atomic`] equivalent of [`ModeResult`].
pub type AModeResultM<A, I> = ModeResultP<A, A, AParseError<A>, I>;

/// [`Atomic`] equivalent of [`ExtensionResult`].
pub type AExtensionResultM<A> = ExtensionResultP<A, A, AParseError<A>>;

/// [`Atomic`] equivalent of [`ExtensionSource`].
pub type AExtensionSourceM<A> = ExtensionSourceP<A, A>;

/// A more generic version of [`Atomic`].
pub trait AtomicModeParse: AtomicBase + ParseMode {
    /// A more generic version of [`Atomic::a_deserialize`].
    fn ma_deserialize<I: Stream>(stream: I) -> AModeResultM<Self, I>;

    /// A more generic version of [`Atomic::a_extend`].
    fn ma_extend(atomic: AExtensionSourceM<Self>, tail: &[u8]) -> AExtensionResultM<Self>;
}

/// External implementation of [`AtomicModeProxy`].
pub trait AtomicModeProxy {
    /// Associated [`AtomicModeParse`].
    type A: AtomicBase + ParseMode;

    /// External implementation of [`AtomicModeParse::ma_deserialize`].
    fn pma_deserialize<I: Stream>(stream: I) -> AModeResultM<Self::A, I>;

    /// External implementation of [`AtomicModeParse::ma_extend`].
    fn pma_extend(atomic: AExtensionSourceM<Self::A>, tail: &[u8]) -> AExtensionResultM<Self::A>;
}

impl<A: AtomicBase + WithParseMode> AtomicModeParse for A
where
    <A as WithParseMode>::WithMode: AtomicModeProxy<A = A>,
{
    fn ma_deserialize<I: Stream>(stream: I) -> AModeResultM<Self, I> {
        <<A as WithParseMode>::WithMode as AtomicModeProxy>::pma_deserialize(stream)
    }

    fn ma_extend(atomic: AExtensionSourceM<Self>, tail: &[u8]) -> AExtensionResultM<Self> {
        <<A as WithParseMode>::WithMode as AtomicModeProxy>::pma_extend(atomic, tail)
    }
}