fusio_log/serdes/
mod.rs

1mod arc;
2mod boolean;
3#[cfg(feature = "bytes")]
4mod bytes;
5mod list;
6mod num;
7pub(crate) mod option;
8mod string;
9
10use std::future::Future;
11
12use thiserror::Error;
13
14use crate::fs::{MaybeSend, SeqRead, Write};
15
16pub trait Encode {
17    type Error: From<fusio::Error> + std::error::Error + Send + Sync + 'static;
18
19    fn encode<W>(
20        &self,
21        writer: &mut W,
22    ) -> impl Future<Output = Result<(), Self::Error>> + MaybeSend
23    where
24        W: Write;
25
26    fn size(&self) -> usize;
27}
28
29impl<T: Encode + Sync> Encode for &T {
30    type Error = T::Error;
31
32    async fn encode<W>(&self, writer: &mut W) -> Result<(), Self::Error>
33    where
34        W: Write,
35    {
36        Encode::encode(*self, writer).await
37    }
38
39    fn size(&self) -> usize {
40        Encode::size(*self)
41    }
42}
43
44pub trait Decode: Sized {
45    type Error: From<fusio::Error> + std::error::Error + Send + Sync + 'static;
46
47    fn decode<R>(reader: &mut R) -> impl Future<Output = Result<Self, Self::Error>> + MaybeSend
48    where
49        R: SeqRead;
50}
51
52#[derive(Debug, Error)]
53#[error("encode error")]
54pub enum EncodeError<E>
55where
56    E: std::error::Error,
57{
58    #[error("io error: {0}")]
59    Io(#[from] std::io::Error),
60    #[error("fusio error: {0}")]
61    Fusio(#[from] fusio::Error),
62    #[error("inner error: {0}")]
63    Inner(#[source] E),
64}
65
66#[derive(Debug, Error)]
67#[error("decode error")]
68pub enum DecodeError<E>
69where
70    E: std::error::Error,
71{
72    #[error("io error: {0}")]
73    Io(#[from] std::io::Error),
74    #[error("fusio error: {0}")]
75    Fusio(#[from] fusio::Error),
76    #[error("inner error: {0}")]
77    Inner(#[source] E),
78}
79
80#[cfg(test)]
81mod tests {
82    use std::io;
83
84    use tokio::io::AsyncSeekExt;
85
86    use super::*;
87
88    #[tokio::test]
89    async fn test_encode_decode() {
90        // Implement a simple struct that implements Encode and Decode
91        struct TestStruct(u32);
92
93        impl Encode for TestStruct {
94            type Error = fusio::Error;
95
96            async fn encode<W>(&self, writer: &mut W) -> Result<(), Self::Error>
97            where
98                W: Write,
99            {
100                self.0.encode(writer).await?;
101
102                Ok(())
103            }
104
105            fn size(&self) -> usize {
106                std::mem::size_of::<u32>()
107            }
108        }
109
110        impl Decode for TestStruct {
111            type Error = fusio::Error;
112
113            async fn decode<R>(reader: &mut R) -> Result<Self, Self::Error>
114            where
115                R: SeqRead,
116            {
117                Ok(TestStruct(u32::decode(reader).await?))
118            }
119        }
120
121        // Test encoding and decoding
122        let original = TestStruct(42);
123        let mut buf = Vec::new();
124        let mut cursor = io::Cursor::new(&mut buf);
125        original.encode(&mut cursor).await.unwrap();
126
127        cursor.seek(std::io::SeekFrom::Start(0)).await.unwrap();
128        let decoded = TestStruct::decode(&mut cursor).await.unwrap();
129
130        assert_eq!(original.0, decoded.0);
131    }
132}