Deserialisation modes

Merge implementations of ConsumesStream and Deterministic for tuple.

It's recommended to first solve this exercise.

#![allow(unused)]
fn main() {
trait Stream: Sized {
    /// Try to read `n` bytes. Consumes the stream on failure.
    fn read_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 stream.
    fn read_all<A>(self, ok: impl FnOnce(&[u8]) -> A) -> A;
}

/// Can be read from a stream.
trait FromStream: Sized {
    type Error;
}

/// Can be constructed from data of any length. Always consumes the stream.
trait ConsumesStream: FromStream {
    /// Try to read the value. Can handle EOF, can ask for all data the stream has.
    fn read_from(stream: impl Stream) -> Result<Self, Self::Error>;

    /// Push extra data into the value.
    fn extend(self, data: &[u8]) -> Result<Self, Self::Error>;
}

/// Whether the reading is terminated, is only determined by the data already read.
trait Deterministic: FromStream {
    /// Returns the stream, as it shouldn't succeed on unexpected EOF.
    fn read_from<S: Stream>(stream: S) -> Result<(Self, S), Self::Error>;

    /// Always fail on extra data.
    fn fail(data: &[u8]) -> Self::Error;
}

enum Either<L, R> {
    Left(L),
    Right(R),
}

impl<A: FromStream, B: FromStream> FromStream for (A, B) {
    type Error = Either<A::Error, B::Error>;
}

impl<A: Deterministic, B: ConsumesStream> ConsumesStream for (A, B) {
    fn read_from(stream: impl Stream) -> Result<Self, Self::Error> {
        let (a, stream) = A::read_from(stream)
            .map_err(Either::Left)?;
        B::read_from(stream)
            .map_err(Either::Right)
            .map(|b| (a, b))
    }

    fn extend(self, data: &[u8]) -> Result<Self, Self::Error> {
        self.1.extend(data)
            .map_err(Either::Right).map(|b| (self.0, b))
    }
}

impl<A: Deterministic, B: Deterministic> Deterministic for (A, B) {
    fn read_from<S: Stream>(stream: S) -> Result<(Self, S), Self::Error> {
        let (a, stream) = A::read_from(stream)
            .map_err(Either::Left)?;
        B::read_from(stream)
            .map_err(Either::Right)
            .map(|(b, stream)| ((a, b), stream))
    }

    fn fail(data: &[u8]) -> Self::Error {
        Either::Right(B::fail(data))
    }
}
}