use std::{io::{Read, Write}, collections::HashMap, hash::Hash, mem::{ManuallyDrop, MaybeUninit}};
use crate::{error::{BinverseError, BinverseResult}, serialize::{Deserialize, Serialize, SizeBytes, SizedDeserialize, SizedSerialize}, streams::{Deserializer, Serializer}};
impl<W: Write> Serialize<W> for bool {
fn serialize(&self, s: &mut Serializer<W>) -> BinverseResult<()> {
s.write(&[*self as u8])
}
}
impl<R: Read> Deserialize<R> for bool {
fn deserialize(d: &mut Deserializer<R>) -> BinverseResult<Self> {
let mut buf = [0];
d.read(&mut buf)?;
match buf[0] {
0 => Ok(false),
1 => Ok(true),
_ => Err(BinverseError::InvalidData)
}
}
}
macro_rules! number_impls {
($($t: ty, $bytes: expr),*) => {
$(
impl<W: Write> Serialize<W> for $t {
fn serialize(&self, s: &mut Serializer<W>) -> BinverseResult<()> {
s.write(&self.to_le_bytes())
}
}
impl<R: Read> Deserialize<R> for $t {
fn deserialize(d: &mut Deserializer<R>) -> BinverseResult<Self> {
let mut b = [0; $bytes];
d.read(&mut b)?;
Ok(<$t>::from_le_bytes(b))
}
}
)*
};
}
number_impls!(
u8, 1, i8, 1,
u16, 2, i16, 2,
u32, 4, i32, 4,
u64, 8, i64, 8,
u128, 16, i128, 16,
f32, 4,
f64, 8
);
impl<W: Write, T, const N: usize> Serialize<W> for [T; N]
where T: Serialize<W> {
fn serialize(&self, s: &mut Serializer<W>) -> BinverseResult<()> {
for elem in self {
elem.serialize(s)?;
}
Ok(())
}
}
struct InitializingArray<T, const N: usize> {
inner: ManuallyDrop<[T; N]>,
initialized_to: usize
}
impl<T, const N: usize> InitializingArray<T, N> {
fn new() -> Self {
Self {
inner: unsafe { MaybeUninit::uninit().assume_init() },
initialized_to: 0
}
}
fn push(&mut self, t: T) {
assert!(self.initialized_to < N);
unsafe { std::ptr::write(&mut self.inner[self.initialized_to], t) };
self.initialized_to += 1;
}
fn get(self) -> [T; N] {
assert_eq!(self.inner.len(), self.initialized_to);
let v = unsafe {
let inner = std::ptr::read(&self.inner);
let _initialized_to = std::ptr::read(&self.initialized_to);
std::mem::forget(self);
ManuallyDrop::into_inner(inner)
};
v
}
}
impl<T, const N: usize> Drop for InitializingArray<T, N> {
fn drop(&mut self) {
unsafe { std::ptr::drop_in_place(std::slice::from_raw_parts_mut(self.inner.as_mut_ptr(), self.initialized_to));};
}
}
impl<R: Read, T: Deserialize<R>, const N: usize> Deserialize<R> for [T; N] {
fn deserialize(d: &mut Deserializer<R>) -> BinverseResult<Self> {
let mut init_arr = InitializingArray::new();
for _ in 0..N {
let x = d.deserialize()?;
init_arr.push(x);
}
Ok(init_arr.get())
}
}
impl<W: Write, T: Serialize<W>> Serialize<W> for Option<T> {
fn serialize(&self, s: &mut Serializer<W>) -> BinverseResult<()> {
if let Some(e) = self {
1_u8.serialize(s)?;
e.serialize(s)?;
} else {
0_u8.serialize(s)?;
}
Ok(())
}
}
impl<R: Read, T: Deserialize<R>> Deserialize<R> for Option<T> {
fn deserialize(d: &mut Deserializer<R>) -> BinverseResult<Self> {
Ok(match d.deserialize()? {
0_u8 => None,
1_u8 => Some(d.deserialize()?),
_ => return Err(BinverseError::InvalidData)
})
}
}
macro_rules! tuples {
($($($t: ident $elem: tt)*;)*) => {
$(
impl<W: Write, $($t: Serialize<W>),*> Serialize<W> for ($($t),*) {
fn serialize(&self, s: &mut Serializer<W>) -> BinverseResult<()> {
$( self.$elem.serialize(s)?; )*
Ok(())
}
}
impl<R: Read, $($t: Deserialize<R>),*> Deserialize<R> for ($($t),*) {
fn deserialize(d: &mut Deserializer<R>) -> BinverseResult<Self> {
Ok(($( <$t as $crate::serialize::Deserialize<R>>::deserialize(d)?, )*))
}
}
)*
}
}
tuples! {
A 0 B 1;
A 0 B 1 C 2;
A 0 B 1 C 2 D 3;
A 0 B 1 C 2 D 3 E 4;
A 0 B 1 C 2 D 3 E 4 F 5;
A 0 B 1 C 2 D 3 E 4 F 5 G 6;
A 0 B 1 C 2 D 3 E 4 F 5 G 6 H 7;
A 0 B 1 C 2 D 3 E 4 F 5 G 6 H 7 I 8;
A 0 B 1 C 2 D 3 E 4 F 5 G 6 H 7 I 8 J 9;
A 0 B 1 C 2 D 3 E 4 F 5 G 6 H 7 I 8 J 9 K 10;
A 0 B 1 C 2 D 3 E 4 F 5 G 6 H 7 I 8 J 9 K 10 L 11;
A 0 B 1 C 2 D 3 E 4 F 5 G 6 H 7 I 8 J 9 K 10 L 11 M 11;
A 0 B 1 C 2 D 3 E 4 F 5 G 6 H 7 I 8 J 9 K 10 L 11 M 11 N 12;
A 0 B 1 C 2 D 3 E 4 F 5 G 6 H 7 I 8 J 9 K 10 L 11 M 11 N 12 O 13;
A 0 B 1 C 2 D 3 E 4 F 5 G 6 H 7 I 8 J 9 K 10 L 11 M 11 N 12 O 13 P 14;
A 0 B 1 C 2 D 3 E 4 F 5 G 6 H 7 I 8 J 9 K 10 L 11 M 11 N 12 O 13 P 14 Q 15;
}
impl<W: Write> SizedSerialize<W> for &str {
fn serialize_sized(&self, s: &mut Serializer<W>, size: usize) -> BinverseResult<()> {
s.write(self[..size].as_bytes())
}
fn size(&self) -> usize {
self.len()
}
}
macro_rules! ser_sized {
($({$t: ty [$($generic: tt),*] [$([$($tree: tt)*]),*]})*) => {
$(
impl<W: Write, $($generic),*> Serialize<W> for $t
where $($($tree)*)* {
fn serialize(&self, s: &mut Serializer<W>) -> BinverseResult<()> {
s.serialize_sized(SizeBytes::Var, self)
}
}
)*
}
}
macro_rules! deser_sized {
($({$t: ty [$($generic: tt),*] [$([$($tree: tt)*]),*]})*) => {
$(
impl<R: Read, $($generic),*> Deserialize<R> for $t
where $($($tree)*)* {
fn deserialize(d: &mut Deserializer<R>) -> BinverseResult<Self> {
d.deserialize_sized(SizeBytes::Var)
}
}
)*
}
}
ser_sized!{ {&str [][]} {String [][]} {&[T] [T] [[T: Serialize<W>]]} {Vec<T> [T] [[T: Serialize<W>]]} {HashMap<K, V> [K, V] [[K: Serialize<W>, V: Serialize<W>]]} }
deser_sized!{ {String [][]} {Vec<T> [T] [[T: Deserialize<R>]]} {HashMap<K, V> [K, V] [[K: Deserialize<R> + Eq + Hash, V: Deserialize<R>]]} }
impl<W: Write> SizedSerialize<W> for String {
fn serialize_sized(&self, s: &mut Serializer<W>, size: usize) -> BinverseResult<()> {
s.write(self[..size].as_bytes())
}
fn size(&self) -> usize { self.len() }
}
impl<R: Read> SizedDeserialize<R> for String {
fn deserialize_sized(d: &mut Deserializer<R>, size: usize) -> BinverseResult<Self> {
let mut b = vec![0; size];
d.read(&mut b)?;
String::from_utf8(b).or(Err(BinverseError::InvalidUTF8))
}
}
impl<W: Write, T> SizedSerialize<W> for &[T]
where T: Serialize<W> {
fn serialize_sized(&self, s: &mut Serializer<W>, size: usize) -> BinverseResult<()> {
for elem in &self[0..size] {
elem.serialize(s)?;
}
Ok(())
}
fn size(&self) -> usize {
self.len()
}
}
impl<W: Write, T: Serialize<W>> SizedSerialize<W> for Vec<T> {
fn serialize_sized(&self, s: &mut Serializer<W>, size: usize) -> BinverseResult<()> {
self.as_slice().serialize_sized(s, size)
}
fn size(&self) -> usize {
self.len()
}
}
impl<R: Read, T: Deserialize<R>> SizedDeserialize<R> for Vec<T> {
fn deserialize_sized(d: &mut Deserializer<R>, size: usize) -> BinverseResult<Self> {
(0..size).map(|_| d.deserialize()).collect::<BinverseResult<Vec<_>>>()
}
}
impl<W: Write, K: Serialize<W>, V: Serialize<W>> SizedSerialize<W> for HashMap<K, V> {
fn serialize_sized(&self, s: &mut Serializer<W>, size: usize) -> BinverseResult<()> {
for (k, v) in self.iter().take(size) {
k.serialize(s)?;
v.serialize(s)?;
}
Ok(())
}
fn size(&self) -> usize {
self.len()
}
}
impl<R: Read, K: Deserialize<R> + Eq + Hash, V: Deserialize<R>> SizedDeserialize<R> for HashMap<K, V> {
fn deserialize_sized(d: &mut Deserializer<R>, size: usize) -> BinverseResult<Self> {
Ok((0..size).map(|_| Ok((d.deserialize()?, d.deserialize()?))).collect::<BinverseResult<HashMap<K, V>>>()?)
}
}