use crate::*;
use std::cmp::Eq;
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
use std::hash::Hash;
macro_rules! seq_se_rev_impl {
(
$ty:ident <T $(: $tbound1:ident $(+ $tbound2:ident)*)*>
) => {
impl<T> Serialize for $ty<T>
where
T: Serialize,
{
#[inline]
fn serialize_to<S: Serializer>(&self, serializer: &mut S) -> Result<()> {
for item in self.iter().rev() {
item.serialize_to(serializer)?;
}
VarInt64(self.len() as u64).serialize_to(serializer)
}
}
};
}
seq_se_rev_impl! {
Vec<T>
}
seq_se_rev_impl! {
VecDeque<T>
}
seq_se_rev_impl! {
LinkedList<T>
}
seq_se_rev_impl! {
BinaryHeap<T: Ord>
}
macro_rules! seq_se_for_impl {
(
$ty:ident <T $(: $tbound1:ident $(+ $tbound2:ident)*)*>
) => {
impl<T> Serialize for $ty<T>
where
T: Serialize,
{
#[inline]
fn serialize_to<S: Serializer>(&self, serializer: &mut S) -> Result<()> {
for item in self.iter() {
item.serialize_to(serializer)?;
}
VarInt64(self.len() as u64).serialize_to(serializer)
}
}
};
}
seq_se_for_impl! {
BTreeSet<T: Ord>
}
seq_se_for_impl! {
HashSet<T: Eq + Hash>
}
macro_rules! seq_de_impl {
(
$ty:ident <T $(: $tbound1:ident $(+ $tbound2:ident)*)*>
) => {
impl<'a, T> Deserialize<'a> for $ty<T>
where
T: Deserialize<'a> $(+ $tbound1 $(+ $tbound2)*)*,
{
fn deserialize_from<D: Deserializer<'a>>(buf: &mut D) -> Result<Self>
where
Self: Sized,
{
let len = VarInt64::deserialize_from(buf)?.0 as usize;
(0..len).map(|_| T::deserialize_from(buf)).collect::<Result<Self>>()
}
}
};
}
seq_de_impl! {
Vec<T>
}
seq_de_impl! {
VecDeque<T>
}
seq_de_impl! {
LinkedList<T>
}
seq_de_impl! {
BinaryHeap<T: Ord>
}
seq_de_impl! {
BTreeSet<T: Ord>
}
seq_de_impl! {
HashSet<T: Eq + Hash>
}
macro_rules! map_impl {
(
$ty:ident <K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V>
) => {
impl<K, V> Serialize for $ty<K, V>
where
K: Serialize,
V: Serialize,
{
#[inline]
fn serialize_to<S: Serializer>(&self, serializer: &mut S) -> Result<()> {
for item in self.iter() {
item.serialize_to(serializer)?;
}
VarInt64(self.len() as u64).serialize_to(serializer)
}
}
impl<'a, K, V> Deserialize<'a> for $ty<K, V>
where
Self: Sized,
K: Deserialize<'a> $(+ $kbound1 $(+ $kbound2)*)*,
V: Deserialize<'a>,
{
#[inline]
fn deserialize_from<D: Deserializer<'a>>(buf: &mut D) -> Result<Self>
where
Self: Sized,
{
let len = VarInt64::deserialize_from(buf)?.0 as usize;
(0..len).map(|_| <(K, V)>::deserialize_from(buf)).collect::<Result<Self>>()
}
}
}
}
map_impl! {
BTreeMap<K: Ord, V>
}
map_impl! {
HashMap<K: Eq + Hash, V>
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_collections() {
{
let ser = vec!["hello", "world", "!"];
let bytes: DownwardBytes = ser.serialize().unwrap();
let der = Vec::<String>::deserialize(&bytes[..]).unwrap();
assert_eq!(ser, der);
assert!(Vec::<u8>::deserialize([128].as_ref()).is_err());
assert!(Vec::<u8>::deserialize([1].as_ref()).is_err());
assert!(Vec::<u8>::deserialize([0].as_ref()).unwrap().is_empty());
}
{
let ser: LinkedList<_> = (0..10).collect();
let bytes: DownwardBytes = ser.serialize().unwrap();
let der = LinkedList::<i32>::deserialize(&bytes[..]).unwrap();
assert_eq!(ser, der);
}
{
let ser = Some("hello".to_string());
let bytes: DownwardBytes = ser.serialize().unwrap();
assert_eq!(bytes.len(), 1 + 1 + 5);
let der = Option::<String>::deserialize(&bytes[..]).unwrap();
assert_eq!(ser, der);
let der = Vec::<String>::deserialize(&bytes[..]).unwrap();
assert_eq!(ser.as_ref(), der.first());
let ser = None;
let bytes: DownwardBytes = ser.serialize().unwrap();
assert_eq!(bytes.len(), 1);
let der = Option::<String>::deserialize(&bytes[..]).unwrap();
assert_eq!(ser, der);
let der = Vec::<String>::deserialize(&bytes[..]).unwrap();
assert_eq!(ser.as_ref(), der.first());
assert!(Option::<String>::deserialize([128].as_ref()).is_err());
assert!(Option::<String>::deserialize([1].as_ref()).is_err());
assert!(Option::<String>::deserialize([0].as_ref())
.unwrap()
.is_none());
}
{
let ser: HashSet<String> = "hello world !".split(' ').map(|s| s.to_owned()).collect();
let bytes: DownwardBytes = ser.serialize().unwrap();
let der = HashSet::<String>::deserialize(&bytes[..]).unwrap();
assert_eq!(ser, der);
assert!(HashSet::<u8>::deserialize([128].as_ref()).is_err());
assert!(HashSet::<u8>::deserialize([1].as_ref()).is_err());
assert!(HashSet::<u8>::deserialize([0].as_ref()).unwrap().is_empty());
}
{
let ser: HashMap<String, u32> = (0..10).map(|i| (i.to_string(), i)).collect();
let bytes: DownwardBytes = ser.serialize().unwrap();
let der = HashMap::<String, u32>::deserialize(&bytes[..]).unwrap();
assert_eq!(ser, der);
let mut der = Vec::<(String, u32)>::deserialize(&bytes[..]).unwrap();
assert_eq!(der.len(), 10);
der.sort();
assert_eq!(der[0].0, "0");
assert_eq!(der[9].0, "9");
}
}
}