fusio_log/serdes/
option.rs

1use fusio::{SeqRead, Write};
2
3use super::{Decode, DecodeError, Encode, EncodeError};
4
5impl<V> Encode for Option<V>
6where
7    V: Encode + Sync,
8{
9    type Error = EncodeError<V::Error>;
10
11    async fn encode<W>(&self, writer: &mut W) -> Result<(), Self::Error>
12    where
13        W: Write,
14    {
15        match self {
16            None => 0u8.encode(writer).await?,
17            Some(v) => {
18                1u8.encode(writer).await?;
19                v.encode(writer).await.map_err(EncodeError::Inner)?;
20            }
21        }
22        Ok(())
23    }
24
25    fn size(&self) -> usize {
26        match self {
27            None => 1,
28            Some(v) => 1 + v.size(),
29        }
30    }
31}
32
33impl<V> Decode for Option<V>
34where
35    V: Decode,
36{
37    type Error = DecodeError<V::Error>;
38
39    async fn decode<R: SeqRead>(reader: &mut R) -> Result<Self, Self::Error> {
40        match u8::decode(reader).await? {
41            0 => Ok(None),
42            1 => Ok(Some(V::decode(reader).await.map_err(DecodeError::Inner)?)),
43            _ => panic!("invalid option tag"),
44        }
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use std::io::Cursor;
51
52    use tokio::io::AsyncSeekExt;
53
54    use crate::serdes::{Decode, Encode};
55
56    #[tokio::test]
57    async fn test_encode_decode() {
58        let source_0 = Some(1u64);
59        let source_1 = None;
60        let source_2 = Some("Hello! Tonbo".to_string());
61
62        let mut bytes = Vec::new();
63        let mut cursor = Cursor::new(&mut bytes);
64
65        source_0.encode(&mut cursor).await.unwrap();
66        source_1.encode(&mut cursor).await.unwrap();
67        source_2.encode(&mut cursor).await.unwrap();
68
69        cursor.seek(std::io::SeekFrom::Start(0)).await.unwrap();
70        let decoded_0 = Option::<u64>::decode(&mut cursor).await.unwrap();
71        let decoded_1 = Option::<u64>::decode(&mut cursor).await.unwrap();
72        let decoded_2 = Option::<String>::decode(&mut cursor).await.unwrap();
73
74        assert_eq!(source_0, decoded_0);
75        assert_eq!(source_1, decoded_1);
76        assert_eq!(source_2, decoded_2);
77    }
78}