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

/// [`Deserializer`] with a cleaner interface for parsing multiple objects
/// from one stream ("inlining").
pub trait Stream: Sized {
    /// Try to read `n` bytes. Consumes the deserializer on failure.
    fn iread_n<A, E>(
        self,
        n: usize,
        ok: impl FnOnce(&[u8]) -> A,
        err: impl FnOnce(&[u8]) -> E,
    ) -> Result<(A, Self), E>;

    /// Read all bytes, consuming the deserializer.
    fn iread_all<A>(self, ok: impl FnOnce(&[u8]) -> A) -> A;

    /// Re-export of [`Deserializer::tell`].
    fn itell(&self) -> usize;
}

/// [`StreamExt::iread_n_const`].
pub trait StreamExt<E>: Stream {
    /// `const`-length equivalent of [`Stream::iread_n`].
    fn iread_n_const<const N: usize>(
        self,
        err: impl FnOnce(&[u8]) -> E,
    ) -> Result<([u8; N], Self), E> {
        self.iread_n(
            N,
            |slice| slice.try_into().expect("`iread_n` wrong length"),
            err,
        )
    }
}

impl<I: Stream, E> StreamExt<E> for I {}

impl<D: ?Sized + Deserializer> Stream for &mut D {
    fn iread_n<A, E>(
        self,
        n: usize,
        ok: impl FnOnce(&[u8]) -> A,
        err: impl FnOnce(&[u8]) -> E,
    ) -> Result<(A, Self), E> {
        let slice = self.read_n(n);
        if slice.len() == n {
            Ok((ok(slice), self))
        } else {
            Err(err(slice))
        }
    }

    fn iread_all<A>(self, ok: impl FnOnce(&[u8]) -> A) -> A {
        ok(self.read_all())
    }

    fn itell(&self) -> usize {
        self.tell()
    }
}

/// [`StreamResultExt::seal`].
pub trait StreamResultExt<A, E> {
    /// Drop the deserializer from parsing result.
    fn seal(self) -> Result<A, E>;
}

impl<A, E, I: Stream> StreamResultExt<A, E> for Result<(A, I), E> {
    fn seal(self) -> Result<A, E> {
        self.map(|(a, _)| a)
    }
}

/// [`From`] for references (of any lifetime).
pub trait FromRef<T: ?Sized>: for<'a> From<&'a T> {
    /// [`From::from(&'a T)`] but without specific `'a`.
    ///
    /// [`From::from(&'a T)`]: From::from
    fn from_ref(value: &T) -> Self {
        Self::from(value)
    }
}

impl<T: ?Sized, U: for<'a> From<&'a T>> FromRef<T> for U {}