use std::{
cmp::Ord,
collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque},
hash::Hash,
};
use crate::{unwrap_return, Serializable, bin_slice, get_vec};
impl Serializable for String {
fn serialize(&self) -> Vec<u8> {
let bytes = self.clone().into_bytes().to_vec();
vec![bytes.len().serialize(), bytes].concat()
}
fn parse(data: &mut Vec<u8>) -> Option<Self> {
let string_byte_length = unwrap_return!(usize::parse(data));
let bytes: Vec<u8> = data.drain(0..string_byte_length).collect();
if bytes.len() != string_byte_length {
return None;
}
String::from_utf8(bytes).ok()
}
}
impl<T: Serializable> Serializable for Vec<T> {
fn serialize(&self) -> Vec<u8> {
let mut stuffs = self.len().serialize();
stuffs.append(&mut bin_slice(self));
stuffs
}
fn parse(data: &mut Vec<u8>) -> Option<Self> {
usize::parse(data).and_then(|length| get_vec(length, data))
}
}
impl<T: Serializable> Serializable for VecDeque<T> {
fn serialize(&self) -> Vec<u8> {
let mut bytes = self.len().serialize();
for item in self.iter() {
bytes.append(&mut item.serialize());
}
bytes
}
fn parse(data: &mut Vec<u8>) -> Option<Self> {
match <Vec<T>>::parse(data) {
Some(parsed) => Some(parsed.into()),
None => None,
}
}
}
impl<T: Serializable> Serializable for LinkedList<T> {
fn serialize(&self) -> Vec<u8> {
let mut bytes = self.len().serialize();
for item in self.iter() {
bytes.append(&mut item.serialize());
}
bytes
}
fn parse(data: &mut Vec<u8>) -> Option<Self> {
let length = unwrap_return!(usize::parse(data));
get_vec(length, data).and_then(|parsed|{
let mut linked_list = Self::new();
for item in parsed {
linked_list.push_back(item);
}
Some(linked_list)
})
}
}
macro_rules! impl_map {
($map_type:ty, $( $key_traits:tt, )*) => {
impl<K: Serializable $( + $key_traits)*, V: Serializable> Serializable for $map_type {
fn serialize(&self) -> Vec<u8> {
let mut bytes = self.len().serialize();
for pair in self {
bytes.append(&mut pair.0.serialize());
bytes.append(&mut pair.1.serialize());
}
bytes
}
fn parse(data: &mut Vec<u8>) -> Option<Self> {
let item_count = unwrap_return!(usize::parse(data));
get_vec::<(K, V)>(item_count, data).and_then(|pairs| {
let mut result = Self::new();
for pair in pairs {
_ = result.insert(pair.0, pair.1)
}
Some(result)
})
}
}
};
}
impl_map!(HashMap<K, V>, Eq, Hash,);
impl_map!(BTreeMap<K, V>, Ord,);
macro_rules! impl_set {
($map_type:ty, $adder_name:ident, $( $key_traits:tt, )*) => {
impl<T: Serializable $( + $key_traits)*> Serializable for $map_type {
fn serialize(&self) -> Vec<u8> {
let mut bytes = self.len().serialize();
for item in self {
bytes.append(&mut item.serialize());
}
bytes
}
fn parse(data: &mut Vec<u8>) -> Option<Self> {
let item_count = unwrap_return!(usize::parse(data));
get_vec::<T>(item_count, data).and_then(|items| {
let mut result = Self::new();
for item in items {
_ = result.$adder_name(item)
}
Some(result)
})
}
}
}
}
impl_set!(HashSet<T>, insert, Eq, Hash,);
impl_set!(BTreeSet<T>, insert, Ord,);
impl_set!(BinaryHeap<T>, push, Ord,);