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