bincake_core/
serialize.rs1use taped::Tape;
14
15use crate::{DecodeError, EncodeError, Read, StringSize, Vec32, Write};
16
17#[macro_export]
19macro_rules! stream {
20 ($($data:expr),* $(,)? => $dest:expr) => {
21 {
22 let mut result;
23 'cases: {
24 $(
25 result = $dest.write(&$data);
26 if result.is_err() {
27 break 'cases;
28 }
29 )*
30 }
31 result
32 }
33 };
34}
35
36pub trait Serialize: Sized {
38 fn encode(&self, dest: &mut Vec<u8>) -> Result<(), EncodeError>;
40
41 fn decode(src: &mut Tape<'_, u8>) -> Result<Self, DecodeError>;
45}
46
47impl Serialize for bool {
48 fn encode(&self, dest: &mut Vec<u8>) -> Result<(), EncodeError> {
49 dest.push(if *self { 1u8 } else { 0u8 });
50 Ok(())
51 }
52
53 fn decode(src: &mut Tape<'_, u8>) -> Result<Self, DecodeError> {
54 src.next()
55 .ok_or(DecodeError::Exhausted { pos: src.pos })
56 .map(|b| b == 1)
57 }
58}
59
60impl Serialize for String {
61 fn encode(&self, dest: &mut Vec<u8>) -> Result<(), EncodeError> {
62 let len = self.len();
63 let len32 = StringSize::try_from(len).map_err(|_| EncodeError::LengthExceedsPrefix {
64 prefix_size: 32,
65 len,
66 })?;
67 dest.write(&len32)?;
68 dest.extend_from_slice(self.as_bytes());
69 Ok(())
70 }
71
72 fn decode(src: &mut Tape<'_, u8>) -> Result<Self, DecodeError> {
73 let start = src.pos;
74 let data = src.read::<Vec32<u8>>()?.into();
75 String::from_utf8(data).map_err(|e| DecodeError::Other {
76 pos: start,
77 cause: format!("Invalid UTF-8 ({e})"),
78 })
79 }
80}