bincake_core/
serialize.rs1use taped::Tape;
14
15use crate::{DecodeError, EncodeError, Read, 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 #[cfg(target_pointer_width = "64")]
64 if len > u32::MAX as usize {
65 return Err(EncodeError::LengthExceedsPrefix {
66 prefix_size: 32,
67 len,
68 });
69 }
70 dest.write(&len)?;
71 dest.extend_from_slice(self.as_bytes());
72 Ok(())
73 }
74
75 fn decode(src: &mut Tape<'_, u8>) -> Result<Self, DecodeError> {
76 let start = src.pos;
77 let data = src.read::<Vec32<u8>>()?.into_inner();
78 String::from_utf8(data).map_err(|e| DecodeError::Other {
79 pos: start,
80 cause: format!("Invalid UTF-8 ({e})"),
81 })
82 }
83}