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