pub const SERIALIZATION_PROTOCOL_VERSION: u64 = 1;
pub trait Serializer {
fn write_u64(&mut self, value: u64);
fn write_f32(&mut self, value: f32);
fn write_bytes(&mut self, bytes: &[u8]);
}
pub trait Deserializer {
fn read_u64(&mut self) -> u64;
fn read_f32(&mut self) -> f32;
fn read_bytes(&mut self, len: usize) -> Vec<u8>;
fn remaining(&self) -> Option<usize> {
None
}
}
pub trait Serialize {
fn serialize<S: Serializer>(&self, serializer: &mut S);
}
pub trait Deserialize: Sized {
fn deserialize<D: Deserializer>(deserializer: &mut D) -> Self;
}
macro_rules! impl_int_serialize {
($($t:ty),*) => {$(
impl Serialize for $t {
fn serialize<S: Serializer>(&self, serializer: &mut S) {
serializer.write_u64(*self as u64);
}
}
impl Deserialize for $t {
fn deserialize<D: Deserializer>(deserializer: &mut D) -> Self {
deserializer.read_u64() as $t
}
}
)*};
}
impl_int_serialize!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
impl Serialize for String {
fn serialize<S: Serializer>(&self, serializer: &mut S) {
serializer.write_u64(self.len() as u64);
serializer.write_bytes(self.as_bytes());
}
}
impl Deserialize for String {
fn deserialize<D: Deserializer>(deserializer: &mut D) -> Self {
let len = deserializer.read_u64() as usize;
if let Some(remaining) = deserializer.remaining() {
assert!(
len <= remaining,
"deserialized string length {len} exceeds the {remaining} bytes left in the input"
);
}
let bytes = deserializer.read_bytes(len);
String::from_utf8(bytes).expect("deserialized string is not valid utf-8")
}
}
impl<A: Serialize, B: Serialize> Serialize for (A, B) {
fn serialize<S: Serializer>(&self, serializer: &mut S) {
self.0.serialize(serializer);
self.1.serialize(serializer);
}
}
impl<A: Deserialize, B: Deserialize> Deserialize for (A, B) {
fn deserialize<D: Deserializer>(deserializer: &mut D) -> Self {
let a = A::deserialize(deserializer);
let b = B::deserialize(deserializer);
(a, b)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct DeserializeError(pub &'static str);
impl core::fmt::Display for DeserializeError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.0)
}
}
impl std::error::Error for DeserializeError {}