1use crate::{FromStream, ToStream, from_stream, numbers::EndianSettings, to_stream};
2
3use std::{
4 collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque},
5 hash::Hash,
6 io::{Read, Result, Write},
7};
8
9pub enum Size {
11 Usize,
13 U8,
15 U16,
17 U32,
19 U64,
21 U128,
23}
24
25pub trait SizeSettings: EndianSettings {
27 const SIZE: Size;
29
30 fn size_to_stream<W: Write>(size: usize, stream: &mut W) -> Result<()> {
32 use Size::*;
33 match Self::SIZE {
34 U8 => to_stream::<Self, _, _>(&(size as u8), stream),
35 U16 => to_stream::<Self, _, _>(&(size as u16), stream),
36 U32 => to_stream::<Self, _, _>(&(size as u32), stream),
37 U64 => to_stream::<Self, _, _>(&(size as u64), stream),
38 U128 => to_stream::<Self, _, _>(&(size as u128), stream),
39 Usize => to_stream::<Self, _, _>(&size, stream),
40 }
41 }
42
43 fn size_from_stream<R: Read>(stream: &mut R) -> Result<usize> {
45 use Size::*;
46 Ok(match Self::SIZE {
47 U8 => from_stream::<Self, u8, _>(stream)? as usize,
48 U16 => from_stream::<Self, u16, _>(stream)? as usize,
49 U32 => from_stream::<Self, u32, _>(stream)? as usize,
50 U64 => from_stream::<Self, u64, _>(stream)? as usize,
51 U128 => from_stream::<Self, u128, _>(stream)? as usize,
52 Usize => from_stream::<Self, usize, _>(stream)?,
53 })
54 }
55}
56
57macro_rules! impl_list_collection {
58 ($t: ident) => {
59 impl<T: ToStream<S>, S: SizeSettings> ToStream<S> for $t<T> {
60 fn to_stream<W: Write>(&self, stream: &mut W) -> Result<()> {
61 S::size_to_stream(self.len(), stream)?;
62
63 for element in self {
64 element.to_stream(stream)?
65 }
66
67 Ok(())
68 }
69 }
70
71 impl<T: FromStream<S>, S: SizeSettings> FromStream<S> for $t<T> {
72 fn from_stream<R: Read>(stream: &mut R) -> Result<Self> {
73 let size = S::size_from_stream(stream)?;
74
75 (0..size)
76 .map(|_| from_stream(stream))
77 .collect::<Result<_>>()
78 }
79 }
80 };
81 ($t: ident, $($rest: ident),+) => {
82 impl_list_collection!($t);
83 impl_list_collection!($($rest),+);
84 };
85}
86
87impl_list_collection!(Vec, VecDeque, LinkedList);
88
89macro_rules! impl_set_collection {
90 ($t: ident, $bound: tt $(+ $others: tt )*) => {
91 impl<T: ToStream<S> + $bound $(+ $others)*, S: SizeSettings> ToStream<S> for $t<T> {
92 fn to_stream<W: Write>(&self, stream: &mut W) -> Result<()> {
93 S::size_to_stream(self.len(), stream)?;
94
95 for element in self {
96 element.to_stream(stream)?
97 }
98
99 Ok(())
100 }
101 }
102
103 impl<T: FromStream<S> + $bound $(+ $others)*, S: SizeSettings> FromStream<S> for $t<T> {
104 fn from_stream<R: Read>(stream: &mut R) -> Result<Self> {
105 let size = S::size_from_stream(stream)?;
106
107 (0..size)
108 .map(|_| from_stream(stream))
109 .collect::<Result<_>>()
110 }
111 }
112 };
113}
114
115impl_set_collection!(HashSet, Eq + Hash);
116impl_set_collection!(BTreeSet, Ord);
117impl_set_collection!(BinaryHeap, Ord);
118
119macro_rules! impl_map_collection {
120 ($t: ident, $bound: tt $(+ $others: tt )*) => {
121 impl<K: ToStream<S> + $bound $(+ $others)*, V: ToStream<S>, S: SizeSettings> ToStream<S> for $t<K, V> {
122 fn to_stream<W: Write>(&self, stream: &mut W) -> Result<()> {
123 S::size_to_stream(self.len(), stream)?;
124
125 for (key, value) in self {
126 key.to_stream(stream)?;
127 value.to_stream(stream)?;
128 }
129
130 Ok(())
131 }
132 }
133
134 impl<K: FromStream<S> + $bound $(+ $others)*, V: FromStream<S>, S: SizeSettings> FromStream<S> for $t<K, V> {
135 fn from_stream<R: Read>(stream: &mut R) -> Result<Self> {
136 let size = S::size_from_stream(stream)?;
137
138 (0..size)
139 .map(|_| Ok((from_stream(stream)?, from_stream(stream)?)))
140 .collect::<Result<_>>()
141 }
142 }
143 };
144}
145
146impl_map_collection!(HashMap, Eq + Hash);
147impl_map_collection!(BTreeMap, Ord);