pub trait Serializable {
fn serialize(&self, buf: &mut impl Extend<u8>);
fn to_bytes(&self) -> Vec<u8> {
let mut v = Vec::new();
self.serialize(&mut v);
v
}
}
impl Serializable for bool {
fn serialize(&self, buf: &mut impl Extend<u8>) {
let id: u32 = if *self { 0x997275b5 } else { 0xbc799737 };
id.serialize(buf);
}
}
impl Serializable for i32 {
fn serialize(&self, buf: &mut impl Extend<u8>) {
buf.extend(self.to_le_bytes());
}
}
impl Serializable for u32 {
fn serialize(&self, buf: &mut impl Extend<u8>) {
buf.extend(self.to_le_bytes());
}
}
impl Serializable for i64 {
fn serialize(&self, buf: &mut impl Extend<u8>) {
buf.extend(self.to_le_bytes());
}
}
impl Serializable for f64 {
fn serialize(&self, buf: &mut impl Extend<u8>) {
buf.extend(self.to_le_bytes());
}
}
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 &[u8] {
fn serialize(&self, buf: &mut impl Extend<u8>) {
let len = self.len();
let (header_len, header): (usize, Vec<u8>) = if len <= 253 {
(1, vec![len as u8])
} else {
(
4,
vec![
0xfe,
(len & 0xff) as u8,
((len >> 8) & 0xff) as u8,
((len >> 16) & 0xff) as u8,
],
)
};
let total = header_len + len;
let padding = (4 - (total % 4)) % 4;
buf.extend(header);
buf.extend(self.iter().copied());
buf.extend(std::iter::repeat_n(0u8, padding));
}
}
impl Serializable for Vec<u8> {
fn serialize(&self, buf: &mut impl Extend<u8>) {
self.as_slice().serialize(buf);
}
}
impl Serializable for String {
fn serialize(&self, buf: &mut impl Extend<u8>) {
self.as_bytes().serialize(buf);
}
}
impl<T: Serializable> Serializable for Vec<T> {
fn serialize(&self, buf: &mut impl Extend<u8>) {
0x1cb5c415u32.serialize(buf);
(self.len() as i32).serialize(buf);
for item in self {
item.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);
for item in &self.0 {
item.serialize(buf);
}
}
}
impl<T: Serializable> Serializable for Option<T> {
fn serialize(&self, buf: &mut impl Extend<u8>) {
if let Some(v) = self {
v.serialize(buf);
}
}
}