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