1use crate::{
4 codec::{Codec, Reader, Writer},
5 varint, Error, SizedCodec,
6};
7use bytes::Bytes;
8use paste::paste;
9
10macro_rules! impl_primitive {
11 ($type:ty, $read_method:ident, $write_method:ident, $size:expr) => {
12 impl Codec for $type {
13 #[inline]
14 fn write(&self, writer: &mut impl Writer) {
15 writer.$write_method(*self);
16 }
17
18 #[inline]
19 fn len_encoded(&self) -> usize {
20 std::mem::size_of::<$type>()
21 }
22
23 #[inline]
24 fn read(reader: &mut impl Reader) -> Result<Self, Error> {
25 reader.$read_method()
26 }
27 }
28
29 impl SizedCodec for $type {
30 const LEN_ENCODED: usize = $size;
31 }
32 };
33}
34
35impl_primitive!(u8, read_u8, write_u8, 1);
36impl_primitive!(u16, read_u16, write_u16, 2);
37impl_primitive!(u32, read_u32, write_u32, 4);
38impl_primitive!(u64, read_u64, write_u64, 8);
39impl_primitive!(u128, read_u128, write_u128, 16);
40impl_primitive!(i8, read_i8, write_i8, 1);
41impl_primitive!(i16, read_i16, write_i16, 2);
42impl_primitive!(i32, read_i32, write_i32, 4);
43impl_primitive!(i64, read_i64, write_i64, 8);
44impl_primitive!(i128, read_i128, write_i128, 16);
45impl_primitive!(f32, read_f32, write_f32, 4);
46impl_primitive!(f64, read_f64, write_f64, 8);
47impl_primitive!(bool, read_bool, write_bool, 1);
48
49impl Codec for Bytes {
51 #[inline]
52 fn write(&self, writer: &mut impl Writer) {
53 writer.write_bytes(self);
54 }
55
56 #[inline]
57 fn len_encoded(&self) -> usize {
58 self.len() + varint::varint_size(self.len() as u64)
59 }
60
61 #[inline]
62 fn read(reader: &mut impl Reader) -> Result<Self, Error> {
63 reader.read_bytes()
64 }
65}
66
67impl<const N: usize> Codec for [u8; N] {
69 #[inline]
70 fn write(&self, writer: &mut impl Writer) {
71 writer.write_fixed(self);
72 }
73
74 #[inline]
75 fn len_encoded(&self) -> usize {
76 N
77 }
78
79 #[inline]
80 fn read(reader: &mut impl Reader) -> Result<Self, Error> {
81 reader.read_fixed()
82 }
83}
84
85impl<const N: usize> SizedCodec for [u8; N] {
86 const LEN_ENCODED: usize = N;
87}
88
89impl<T: Codec> Codec for Option<T> {
91 #[inline]
92 fn write(&self, writer: &mut impl Writer) {
93 writer.write_option(self);
94 }
95
96 #[inline]
97 fn len_encoded(&self) -> usize {
98 match self {
99 Some(inner) => 1 + inner.len_encoded(),
100 None => 1,
101 }
102 }
103
104 #[inline]
105 fn read(reader: &mut impl Reader) -> Result<Self, Error> {
106 reader.read_option()
107 }
108}
109
110macro_rules! impl_codec_for_tuple {
112 ($($index:literal),*) => {
113 paste! {
114 impl<$( [<T $index>]: Codec ),*> Codec for ( $( [<T $index>], )* ) {
115 fn write(&self, writer: &mut impl Writer) {
116 $( self.$index.write(writer); )*
117 }
118
119 fn len_encoded(&self) -> usize {
120 0 $( + self.$index.len_encoded() )*
121 }
122
123 fn read(reader: &mut impl Reader) -> Result<Self, Error> {
124 Ok(( $( [<T $index>]::read(reader)?, )* ))
125 }
126 }
127 }
128 };
129}
130
131impl_codec_for_tuple!(0);
133impl_codec_for_tuple!(0, 1);
134impl_codec_for_tuple!(0, 1, 2);
135impl_codec_for_tuple!(0, 1, 2, 3);
136impl_codec_for_tuple!(0, 1, 2, 3, 4);
137impl_codec_for_tuple!(0, 1, 2, 3, 4, 5);
138impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6);
139impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7);
140impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7, 8);
141impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
142impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
143impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
144
145impl<T: Codec> Codec for Vec<T> {
147 #[inline]
148 fn write(&self, writer: &mut impl Writer) {
149 writer.write_vec(self);
150 }
151
152 #[inline]
153 fn len_encoded(&self) -> usize {
154 let len = varint::varint_size(self.len() as u64);
155 self.iter().map(Codec::len_encoded).sum::<usize>() + len
156 }
157
158 #[inline]
159 fn read(reader: &mut impl Reader) -> Result<Self, Error> {
160 reader.read_vec()
161 }
162}
163
164#[cfg(test)]
165mod tests {
166 use super::*;
167 use crate::codec::{Codec, SizedCodec};
168 use bytes::Bytes;
169
170 macro_rules! impl_num_test {
172 ($type:ty, $size:expr) => {
173 paste! {
174 #[test]
175 fn [<test_ $type>]() {
176 let expected_len = std::mem::size_of::<$type>();
177 let values: [$type; 5] =
178 [0 as $type, 1 as $type, 42 as $type, <$type>::MAX, <$type>::MIN];
179 for value in values.iter() {
180 let encoded = value.encode();
181 assert_eq!(encoded.len(), expected_len);
182 let decoded = <$type>::decode(encoded).unwrap();
183 assert_eq!(*value, decoded);
184 assert_eq!(Codec::len_encoded(value), expected_len);
185 assert_eq!(SizedCodec::len_encoded(value), expected_len);
186
187 let fixed: [u8; $size] = value.encode_fixed();
188 assert_eq!(fixed.len(), expected_len);
189 let decoded = <$type>::decode(Bytes::copy_from_slice(&fixed)).unwrap();
190 assert_eq!(*value, decoded);
191 }
192 }
193 }
194 };
195 }
196 impl_num_test!(u8, 1);
197 impl_num_test!(u16, 2);
198 impl_num_test!(u32, 4);
199 impl_num_test!(u64, 8);
200 impl_num_test!(u128, 16);
201 impl_num_test!(i8, 1);
202 impl_num_test!(i16, 2);
203 impl_num_test!(i32, 4);
204 impl_num_test!(i64, 8);
205 impl_num_test!(i128, 16);
206 impl_num_test!(f32, 4);
207 impl_num_test!(f64, 8);
208
209 #[test]
210 fn test_endianness() {
211 let encoded = 0x0102u16.encode();
213 assert_eq!(encoded, Bytes::from_static(&[0x01, 0x02]));
214
215 let encoded = 0x01020304u32.encode();
217 assert_eq!(encoded, Bytes::from_static(&[0x01, 0x02, 0x03, 0x04]));
218
219 let encoded = 1.0f32.encode();
221 assert_eq!(encoded, Bytes::from_static(&[0x3F, 0x80, 0x00, 0x00])); }
223
224 #[test]
225 fn test_bool() {
226 let values = [true, false];
227 for value in values.iter() {
228 let encoded = value.encode();
229 assert_eq!(encoded.len(), 1);
230 let decoded = bool::decode(encoded).unwrap();
231 assert_eq!(*value, decoded);
232 assert_eq!(Codec::len_encoded(value), 1);
233 assert_eq!(SizedCodec::len_encoded(value), 1);
234 }
235 }
236
237 #[test]
238 fn test_bytes() {
239 let values = [
240 Bytes::new(),
241 Bytes::from_static(&[1, 2, 3]),
242 Bytes::from(vec![0; 300]),
243 ];
244 for value in values {
245 let encoded = value.encode();
246 assert_eq!(
247 encoded.len(),
248 varint::varint_size(value.len() as u64) + value.len()
249 );
250 let decoded = Bytes::decode(encoded).unwrap();
251 assert_eq!(value, decoded);
252 }
253 }
254
255 #[test]
256 fn test_array() {
257 let values = [1u8, 2, 3];
258 let encoded = values.encode();
259 let decoded = <[u8; 3]>::decode(encoded).unwrap();
260 assert_eq!(values, decoded);
261 }
262
263 #[test]
264 fn test_option() {
265 let option_values = [Some(42u32), None];
266 for value in option_values {
267 let encoded = value.encode();
268 let decoded = Option::<u32>::decode(encoded).unwrap();
269 assert_eq!(value, decoded);
270 }
271 }
272
273 #[test]
274 fn test_option_length() {
275 let some = Some(42u32);
276 assert_eq!(Codec::len_encoded(&some), 1 + 4);
277 assert_eq!(some.encode().len(), 1 + 4);
278 let none: Option<u32> = None;
279 assert_eq!(Codec::len_encoded(&none), 1);
280 assert_eq!(none.encode().len(), 1);
281 }
282
283 #[test]
284 fn test_tuple() {
285 let tuple_values = [(1u16, None), (1u16, Some(2u32))];
286 for value in tuple_values {
287 let encoded = value.encode();
288 let decoded = <(u16, Option<u32>)>::decode(encoded).unwrap();
289 assert_eq!(value, decoded);
290 }
291 }
292
293 #[test]
294 fn test_vec() {
295 let vec_values = [vec![], vec![1u8], vec![1u8, 2u8, 3u8]];
296 for value in vec_values {
297 let encoded = value.encode();
298 assert_eq!(encoded.len(), value.len() * std::mem::size_of::<u8>() + 1);
299 let decoded = Vec::<u8>::decode(encoded).unwrap();
300 assert_eq!(value, decoded);
301 }
302 }
303}