pub trait Serializable {
fn serialize(&self, buf: &mut impl Extend<u8>);
fn to_bytes(&self) -> Vec<u8> {
let mut buffer = Vec::new();
self.serialize(&mut buffer);
buffer
}
}
impl Serializable for bool {
#[allow(clippy::unreadable_literal)]
fn serialize(&self, buf: &mut impl Extend<u8>) {
if *self { 0x997275b5u32 } else { 0xbc799737u32 }.serialize(buf)
}
}
impl Serializable for i32 {
fn serialize(&self, buf: &mut impl Extend<u8>) {
buf.extend(self.to_le_bytes().iter().copied())
}
}
impl Serializable for u32 {
fn serialize(&self, buf: &mut impl Extend<u8>) {
buf.extend(self.to_le_bytes().iter().copied())
}
}
impl Serializable for i64 {
fn serialize(&self, buf: &mut impl Extend<u8>) {
buf.extend(self.to_le_bytes().iter().copied())
}
}
impl Serializable for [u8; 16] {
fn serialize(&self, buf: &mut impl Extend<u8>) {
buf.extend(self.iter().copied())
}
}
impl Serializable for [u8; 32] {
fn serialize(&self, buf: &mut impl Extend<u8>) {
buf.extend(self.iter().copied())
}
}
impl Serializable for f64 {
fn serialize(&self, buf: &mut impl Extend<u8>) {
buf.extend(self.to_le_bytes().iter().copied())
}
}
impl<T: Serializable> Serializable for Vec<T> {
#[allow(clippy::unreadable_literal)]
fn serialize(&self, buf: &mut impl Extend<u8>) {
0x1cb5c415u32.serialize(buf);
(self.len() as i32).serialize(buf);
self.iter().for_each(|x| x.serialize(buf));
}
}
impl<T: Serializable> Serializable for crate::RawVec<T> {
fn serialize(&self, buf: &mut impl Extend<u8>) {
(self.0.len() as i32).serialize(buf);
self.0.iter().for_each(|x| x.serialize(buf));
}
}
impl Serializable for String {
fn serialize(&self, buf: &mut impl Extend<u8>) {
self.as_bytes().serialize(buf)
}
}
impl Serializable for Vec<u8> {
fn serialize(&self, buf: &mut impl Extend<u8>) {
(&self[..]).serialize(buf)
}
}
impl Serializable for &[u8] {
fn serialize(&self, buf: &mut impl Extend<u8>) {
let len = if self.len() <= 253 {
buf.extend([self.len() as u8]);
self.len() + 1
} else {
buf.extend([
254,
(self.len() & 0xff) as u8,
((self.len() >> 8) & 0xff) as u8,
((self.len() >> 16) & 0xff) as u8,
]);
self.len()
};
let padding = (4 - (len % 4)) % 4;
buf.extend(self.iter().copied());
buf.extend((0..padding).map(|_| 0));
}
}