fusio_log/serdes/
string.rs1use std::mem::size_of;
2
3use fusio::{SeqRead, Write};
4
5use super::{Decode, Encode};
6
7impl Encode for &str {
8 type Error = fusio::Error;
9
10 async fn encode<W>(&self, writer: &mut W) -> Result<(), Self::Error>
11 where
12 W: Write,
13 {
14 (self.len() as u16).encode(writer).await?;
15 let (result, _) = writer.write_all(self.as_bytes()).await;
16 result?;
17
18 Ok(())
19 }
20
21 fn size(&self) -> usize {
22 size_of::<u16>() + self.len()
23 }
24}
25
26impl Encode for String {
27 type Error = fusio::Error;
28
29 async fn encode<W>(&self, writer: &mut W) -> Result<(), Self::Error>
30 where
31 W: Write,
32 {
33 self.as_str().encode(writer).await
34 }
35
36 fn size(&self) -> usize {
37 self.as_str().size()
38 }
39}
40
41impl Decode for String {
42 type Error = fusio::Error;
43
44 async fn decode<R: SeqRead>(reader: &mut R) -> Result<Self, Self::Error> {
45 let len = u16::decode(reader).await?;
46 let (result, buf) = reader.read_exact(vec![0u8; len as usize]).await;
47 result?;
48
49 Ok(unsafe { String::from_utf8_unchecked(buf.as_slice().to_vec()) })
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use std::io::Cursor;
56
57 use tokio::io::AsyncSeekExt;
58
59 use crate::serdes::{Decode, Encode};
60
61 #[tokio::test]
62 async fn test_encode_decode() {
63 let source_0 = "Hello! World";
64 let source_1 = "Hello! Tonbo".to_string();
65
66 let mut bytes = Vec::new();
67 let mut cursor = Cursor::new(&mut bytes);
68
69 source_0.encode(&mut cursor).await.unwrap();
70 source_1.encode(&mut cursor).await.unwrap();
71
72 cursor.seek(std::io::SeekFrom::Start(0)).await.unwrap();
73 let decoded_0 = String::decode(&mut cursor).await.unwrap();
74 let decoded_1 = String::decode(&mut cursor).await.unwrap();
75
76 assert_eq!(source_0, decoded_0);
77 assert_eq!(source_1, decoded_1);
78 }
79}