viffy 0.1.5

SoA + SIMD automata generator
Documentation
/// Max aspace allowed for the serializer
const MAX_SCRATCH_SPACE: usize = 1 << 28; // 256 MiB

/// This is a "key" + buffer where your serialized/deserialized data
/// will be created at
pub struct Serializer<'a> {
	pub scratchpad: &'a mut [u8],
	pub used_space: usize,
	pub tag: u8,
}

impl<'a> Serializer<'a> {
	pub fn thread_scratchpad(len: usize) -> Vec<u8> {
		vec![0u8; len]
	}

	pub fn new(scratchpad: &'a mut [u8], tag: u8) -> Self {
		Self{
			scratchpad,
			used_space: 0,
			tag
		}
	}

	pub fn serialize_raw(&mut self, data: &[u8]) {
		let offset = self.used_space;
		for (i, &e) in data.iter().enumerate() {
			self.scratchpad[offset + i] = e;
		}
		self.used_space += data.len();
	}

	pub fn deserialize_raw(&mut self, len: usize) -> &[u8] {
		let offset = self.used_space;
		self.used_space += len;
		&self.scratchpad[offset..(offset + len)]
	}
}

pub trait Serializable
where
	Self: Sized
{
	fn serialize(&self, s: &mut Serializer);
	fn deserialize(&mut self, s: &mut Serializer);
	fn serialized_size(&self) -> usize {
		std::mem::size_of::<Self>()
	}
}

macro_rules! primitive_serializer_impl {
	($($x:ident)*) => {
		$(impl Serializable for $x {
			fn serialize(&self, s: &mut Serializer) {
				s.serialize_raw(&Self::to_le_bytes(*self))
			}
			fn deserialize(&mut self, s: &mut Serializer) {
				let len = self.serialized_size();
				let (bytes, _) = s.deserialize_raw(len).split_at(len);
				*self = Self::from_le_bytes(bytes.try_into().unwrap());
			}
		})*
	}
}
primitive_serializer_impl!(u8 u16 u32 u64 i8 i16 i32 i64 f32 f64);

impl Serializable for bool {
	fn serialize(&self, s: &mut Serializer) {
		let b = *self as u8;
		<u8 as Serializable>::serialize(&b, s);
	}
	fn deserialize(&mut self, s: &mut Serializer) {
		let mut tmp = 0;
		<u8 as Serializable>::deserialize(&mut tmp, s);
		*self = tmp != 0;
	}
}

impl<T: Serializable + Default> Serializable for Option<T> {
    fn serialize(&self, s: &mut Serializer) {
        let has_value = self.is_some();
        <bool as Serializable>::serialize(&has_value, s);
        if let Some(inner) = self {
            <T as Serializable>::serialize(inner, s);
        }
    }
    fn deserialize(&mut self, s: &mut Serializer) {
        let mut has_value = false;
        <bool as Serializable>::deserialize(&mut has_value, s);
        if has_value {
            let mut data = T::default();
            <T as Serializable>::deserialize(&mut data, s);
            self.insert(data);
        } else {
            *self = None;
        }
    }
    fn serialized_size(&self) -> usize {
        let has_value = self.is_some();
        let mut size = has_value.serialized_size();
        if let Some(inner) = self {
            size += inner.serialized_size();
        }
        size
    }
}

impl<T: Serializable, const N: usize> Serializable for [T; N] {
	fn serialize(&self, s: &mut Serializer) {
		for i in 0..self.len() {
			self[i].serialize(s);
		}
	}
	fn deserialize(&mut self, s: &mut Serializer) {
		for i in 0..self.len() {
			self[i].deserialize(s);
		}
	}
}

impl<T: Serializable + Default> Serializable for Vec<T> {
	fn serialize(&self, s: &mut Serializer) {
		let len_16 = self.len() as u16;
		<u16 as Serializable>::serialize(&len_16, s);
		for i in 0..self.len() {
			<T as Serializable>::serialize(&self[i], s);
		}
	}
	fn deserialize(&mut self, s: &mut Serializer) {
		let mut len_16 = 0;
		<u16 as Serializable>::deserialize(&mut len_16, s);
		self.resize_with(len_16 as usize, || T::default());
		for i in 0..(len_16 as usize) {
			<T as Serializable>::deserialize(&mut self[i], s);
		}
	}
}

impl Serializable for String {
    fn serialize(&self, s: &mut Serializer) {
        let bytes = self.as_bytes();
		let len_16 = bytes.len() as u16;
		<u16 as Serializable>::serialize(&len_16, s);
		for i in 0..bytes.len() {
			<u8 as Serializable>::serialize(&bytes[i], s);
		}
    }
	fn deserialize(&mut self, s: &mut Serializer) {
		let mut len_16 = 0;
		<u16 as Serializable>::deserialize(&mut len_16, s);
		let mut bytes = vec![0u8; len_16 as usize];
		for i in 0..(len_16 as usize) {
			<u8 as Serializable>::deserialize(&mut bytes[i], s);	
		}
        *self = unsafe { String::from_raw_parts(bytes.as_mut_ptr(), bytes.len(), bytes.len()) };
	}
}

macro_rules! tuple_serializer_impl {
	() => {};
	($head:ident $head_num:tt; $($tail:ident $tail_num:tt;)*) => {
		impl<$head, $($tail),*> Serializable for ($head, $($tail),*)
		where
			$head: Serializable,
			$($tail: Serializable,)*
		{
			fn serialize(&self, s: &mut Serializer) {
				<$head as Serializable>::serialize(&self.$head_num, s);
				$(<$tail as Serializable>::serialize(&self.$tail_num, s);)*
			}
			fn deserialize(&mut self, s: &mut Serializer) {
				<$head as Serializable>::deserialize(&mut self.$head_num, s);
				$(<$tail as Serializable>::deserialize(&mut self.$tail_num, s);)*
			}
		}
	}
}
tuple_serializer_impl!(A 0; B 1;);
tuple_serializer_impl!(A 0; B 1; C 2;);
tuple_serializer_impl!(A 0; B 1; C 2; D 3;);
tuple_serializer_impl!(A 0; B 1; C 2; D 3; E 4;);
tuple_serializer_impl!(A 0; B 1; C 2; D 3; E 4; F 5;);

impl<const N: usize> Serializable for crate::math::Vector<N> {
	fn serialize(&self, s: &mut Serializer) {
		for item in self.0.iter() {
			item.serialize(s);
		}
	}
	fn deserialize(&mut self, s: &mut Serializer) {
		for item in self.0.iter_mut() {
			item.deserialize(s);
		}
	}
}

impl Serializable for crate::Color3 {
	fn serialize(&self, s: &mut Serializer) {
		self.0.serialize(s);
		self.1.serialize(s);
		self.2.serialize(s);
	}
	fn deserialize(&mut self, s: &mut Serializer) {
		self.0.deserialize(s);
		self.1.deserialize(s);
		self.2.deserialize(s);
	}
}

impl Serializable for crate::AlnumPacked3 {
	fn serialize(&self, s: &mut Serializer) {
		self.0.serialize(s);
		self.1.serialize(s);
		self.2.serialize(s);
	}
	fn deserialize(&mut self, s: &mut Serializer) {
		self.0.deserialize(s);
		self.1.deserialize(s);
		self.2.deserialize(s);
	}
}

impl<T: Serializable + std::cmp::Ord + Default> Serializable for std::collections::BTreeSet<T> {
	fn serialize(&self, s: &mut Serializer) {
		let len_16 = self.len() as u16;
		<u16 as Serializable>::serialize(&len_16, s);
		for item in self.iter() {
			<T as Serializable>::serialize(&item, s);
		}
	}
	fn deserialize(&mut self, s: &mut Serializer) {
		let mut len_16 = 0;
		len_16.deserialize(s);
		self.clear();
		for i in 0..(len_16 as usize) {
			let mut item = T::default();
			item.deserialize(s);
			self.insert(item);
		}
	}
}

impl<K: Serializable + std::cmp::Ord + Default, V: Serializable + Default> Serializable for std::collections::BTreeMap<K, V> {
	fn serialize(&self, s: &mut Serializer) {
		let len_16 = self.len() as u16;
		len_16.serialize(s);
		for item in self.iter() {
			item.0.serialize(s);
			item.1.serialize(s);
		}
	}
	fn deserialize(&mut self, s: &mut Serializer) {
		let mut len_16 = 0;
		len_16.deserialize(s);
		self.clear();
		for i in 0..(len_16 as usize) {
			let mut k = K::default();
			let mut v = V::default();
			k.deserialize(s);
			v.deserialize(s);
			self.insert(k, v);
		}
	}
}

#[macro_export]
macro_rules! enum_serializer_impl {
	($x:ident $y:ident) => {
		impl self::Serializable for $x {
			fn serialize(&self, s: &mut self::Serializer) {
				let tmp = *self as $y;
				tmp.serialize(s);
			}
			fn deserialize(&mut self, s: &mut self::Serializer) {
				let mut tmp = 0 as $y;
				tmp.deserialize(s);
				*self = unsafe { std::mem::transmute::<_, Self>(tmp) };
			}
		}
	};
}