1use std::{
2 collections::{HashMap, HashSet},
3 io::{Read, Write},
4};
5
6use indexmap::{IndexMap, IndexSet};
7
8use super::{
9 packed_int::PackedUint, DataFormat, DataFormatReader, DataFormatWriter, DataReadError,
10 DataWriteError,
11};
12
13impl<T: DataFormat + Default + Copy, const N: usize> DataFormat for [T; N] {
14 type Header = T::Header;
15 const LATEST_HEADER: Self::Header = T::LATEST_HEADER;
16
17 fn write_data<W: Write>(&self, writer: &mut W) -> Result<usize, DataWriteError> {
18 let mut written = 0;
19 for item in self.iter() {
20 written += item.write_data(writer)?;
21 }
22 Ok(written)
23 }
24
25 fn read_data<R: Read>(reader: &mut R, header: &Self::Header) -> Result<Self, DataReadError> {
26 let mut data = [T::default(); N];
27 for item in data.iter_mut() {
28 *item = reader.read_data(header)?;
29 }
30 Ok(data)
31 }
32}
33
34impl<T: DataFormat> DataFormat for Vec<T> {
35 type Header = T::Header;
36 const LATEST_HEADER: Self::Header = T::LATEST_HEADER;
37
38 fn write_data<W: Write>(&self, writer: &mut W) -> Result<usize, DataWriteError> {
39 let mut written = PackedUint::from(self.len()).write_data(writer)?;
40 for item in self.iter() {
41 written += writer.write_data(item)?;
42 }
43 Ok(written)
44 }
45
46 fn read_data<R: Read>(reader: &mut R, header: &Self::Header) -> Result<Self, DataReadError> {
47 let len = usize::from(PackedUint::read_data(reader, &())?);
48 let mut data = Vec::with_capacity(len);
49 for _ in 0..len {
50 data.push(reader.read_data(header)?);
51 }
52 Ok(data)
53 }
54}
55
56macro_rules! impl_set {
57 ($set_ty:ident) => {
58 impl<T> DataFormat for $set_ty<T>
59 where
60 T: DataFormat + Eq + std::hash::Hash,
61 {
62 type Header = T::Header;
63 const LATEST_HEADER: Self::Header = T::LATEST_HEADER;
64
65 fn write_data<W: Write>(&self, writer: &mut W) -> Result<usize, DataWriteError> {
66 let mut written = PackedUint::from(self.len()).write_data(writer)?;
67 for item in self.iter() {
68 written += writer.write_data(item)?;
69 }
70 Ok(written)
71 }
72
73 fn read_data<R: Read>(
74 reader: &mut R,
75 header: &Self::Header,
76 ) -> Result<Self, DataReadError> {
77 let len = usize::from(PackedUint::read_data(reader, &())?);
78 let mut data = $set_ty::with_capacity(len);
79 for _ in 0..len {
80 data.insert(reader.read_data(header)?);
81 }
82 Ok(data)
83 }
84 }
85 };
86}
87
88impl_set!(HashSet);
89impl_set!(IndexSet);
90
91macro_rules! impl_map {
92 ($map_ty:ident) => {
93 impl<K, V> DataFormat for $map_ty<K, V>
94 where
95 K: DataFormat + Eq + std::hash::Hash,
96 V: DataFormat,
97 {
98 type Header = (K::Header, V::Header);
99 const LATEST_HEADER: Self::Header = (K::LATEST_HEADER, V::LATEST_HEADER);
100
101 fn write_data<W: Write>(&self, writer: &mut W) -> Result<usize, DataWriteError> {
102 let mut written = PackedUint::from(self.len()).write_data(writer)?;
103 for (key, value) in self.iter() {
104 written += writer.write_data(key)?;
105 written += writer.write_data(value)?;
106 }
107 Ok(written)
108 }
109
110 fn read_data<R: Read>(
111 reader: &mut R,
112 (key_header, value_header): &Self::Header,
113 ) -> Result<Self, DataReadError> {
114 let len = usize::from(PackedUint::read_data(reader, &())?);
115 let mut data = $map_ty::with_capacity(len);
116 for _ in 0..len {
117 data.insert(
118 reader.read_data(key_header)?,
119 reader.read_data(value_header)?,
120 );
121 }
122 Ok(data)
123 }
124 }
125 };
126}
127
128impl_map!(HashMap);
129impl_map!(IndexMap);
130
131#[cfg(test)]
132#[rustfmt::skip]
133mod test {
134 use crate::format::DataFormat;
135
136 macro_rules! case {
137 ($name:ident, $ty:ty, $a:expr, $b:expr) => {
138 #[test]
139 fn $name() {
140 let mut data = Vec::new();
141 let value: $ty = $a;
142 value.write_data(&mut data).unwrap();
143 let mut reader = &data[..];
148 let read_value = <$ty>::read_data(&mut reader, &<$ty as DataFormat>::LATEST_HEADER).unwrap();
149 assert_eq!(read_value, value);
150
151 }
152
153 };
154 }
155
156 case!(test_vec_u8, Vec<u8>, vec![1, 2, 3], [
157 1, 3,
158 1, 2, 3
159 ]);
160 case!(test_vec_u16, Vec<u16>, vec![1, 2, 3], [
161 1, 3,
162 1, 0,
163 2, 0,
164 3, 0
165 ]);
166
167 case!(test_hashset_u8, std::collections::HashSet<u8>, [1, 2, 3].into_iter().collect(), [
168 1, 3,
169 1, 2, 3
170 ]);
171 case!(test_hashset_u16, std::collections::HashSet<u16>, [1, 2, 3].into_iter().collect(), [
172 1, 3,
173 1, 0,
174 2, 0,
175 3, 0
176 ]);
177
178 case!(test_hashmap_u8_u16, std::collections::HashMap<u8, u16>, [(1, 2), (3, 4)].into_iter().collect(), [
179 1, 4,
180 1, 0,
181 2, 0,
182 3, 0,
183 4, 0
184 ]);
185}