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 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 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}