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
use crate::serde::{Datum, OptDatum, ReadResult, WriteLen};
use anyhow::{anyhow, Result};
use std::any;
use std::borrow::Borrow;
use std::io::{Cursor, Read, Seek, Write};

pub trait Ser {
    fn ser<W: Write>(&self, w: &mut W) -> Result<WriteLen>;

    fn ser_solo(&self) -> Result<Vec<u8>> {
        let mut buf = vec![];
        self.ser(&mut buf)?;
        Ok(buf)
    }
}
pub trait Deser: Sized {
    fn skip<R: Read + Seek>(r: &mut R) -> Result<ReadResult<()>>;
    fn deser<R: Read + Seek>(r: &mut R) -> Result<ReadResult<Self>>;

    fn deser_solo(buf: &[u8]) -> Result<Self> {
        let mut r = Cursor::new(&buf);
        match Self::deser(&mut r)? {
            ReadResult::EOF => Err(anyhow!("No data")),
            ReadResult::Some(_, moi) => Ok(moi),
        }
    }
}

/* Blanket impls for Ser */
impl<T> Ser for T
where
    T: Borrow<Datum>,
{
    fn ser<W: Write>(&self, w: &mut W) -> Result<WriteLen> {
        let dat: &Datum = self.borrow();
        dat.ser(w)
    }
}
impl<T> Ser for OptDatum<T>
where
    T: Borrow<Datum>,
{
    fn ser<W: Write>(&self, w: &mut W) -> Result<WriteLen> {
        match self {
            OptDatum::Tombstone => OptDatum::Tombstone.ser(w),
            OptDatum::Some(t) => {
                let dat: &Datum = t.borrow();
                dat.ser(w)
            }
        }
    }
}

/* Blanket impls for Deser */
impl<T, E> Deser for T
where
    T: TryFrom<Datum, Error = E>,
    E: Into<anyhow::Error>,
{
    fn skip<R: Read + Seek>(r: &mut R) -> Result<ReadResult<()>> {
        OptDatum::<Datum>::skip(r)
    }
    fn deser<R: Read + Seek>(r: &mut R) -> Result<ReadResult<Self>> {
        match OptDatum::<Datum>::deser(r)? {
            ReadResult::EOF => Ok(ReadResult::EOF),
            ReadResult::Some(_, OptDatum::Tombstone) => Err(anyhow!(
                "Tombstone while reading {}",
                any::type_name::<Self>()
            )),
            ReadResult::Some(r_len, OptDatum::Some(dat)) => {
                let moi = Self::try_from(dat).map_err(|e| anyhow!(e))?;
                Ok(ReadResult::Some(r_len, moi))
            }
        }
    }
}
impl<T, E> Deser for OptDatum<T>
where
    T: TryFrom<Datum, Error = E>,
    E: Into<anyhow::Error>,
{
    fn skip<R: Read + Seek>(r: &mut R) -> Result<ReadResult<()>> {
        OptDatum::<Datum>::skip(r)
    }
    fn deser<R: Read + Seek>(r: &mut R) -> Result<ReadResult<Self>> {
        match OptDatum::<Datum>::deser(r)? {
            ReadResult::EOF => Ok(ReadResult::EOF),
            ReadResult::Some(r_len, OptDatum::Tombstone) => {
                Ok(ReadResult::Some(r_len, OptDatum::Tombstone))
            }
            ReadResult::Some(r_len, OptDatum::Some(dat)) => {
                let t = T::try_from(dat).map_err(|e| anyhow!(e))?;
                Ok(ReadResult::Some(r_len, OptDatum::Some(t)))
            }
        }
    }
}

/* trait Serializable */
pub trait Serializable: Ser + Deser {}