commonware_codec/types/
tuple.rs

1//! Codec implementation for tuples.
2
3use crate::{Config, EncodeSize, Error, Read, Write};
4use bytes::{Buf, BufMut};
5use paste::paste;
6
7// Tuple implementation
8// Each type must have the same configuration type for reading.
9macro_rules! impl_codec_for_tuple {
10    ($($index:literal),*) => {
11        paste! {
12            impl<$( [<T $index>]: EncodeSize ),*> EncodeSize for ( $( [<T $index>], )* ) {
13                #[inline]
14                fn encode_size(&self) -> usize {
15                    0 $( + self.$index.encode_size() )*
16                }
17            }
18
19            impl<$( [<T $index>]: Write ),*> Write for ( $( [<T $index>], )* ) {
20                #[inline]
21                fn write(&self, buf: &mut impl BufMut) {
22                    $( self.$index.write(buf); )*
23                }
24            }
25
26            impl <Cfg: Config, $( [<T $index>]: Read<Cfg> ),*> Read<Cfg> for ( $( [<T $index>], )* ) {
27                #[inline]
28                fn read_cfg(buf: &mut impl Buf, cfg: &Cfg) -> Result<Self, Error> {
29                    Ok(( $( [<T $index>]::read_cfg(buf, cfg)?, )* ))
30                }
31            }
32        }
33    };
34}
35
36// Generate implementations for tuple sizes 1 through 12
37impl_codec_for_tuple!(0);
38impl_codec_for_tuple!(0, 1);
39impl_codec_for_tuple!(0, 1, 2);
40impl_codec_for_tuple!(0, 1, 2, 3);
41impl_codec_for_tuple!(0, 1, 2, 3, 4);
42impl_codec_for_tuple!(0, 1, 2, 3, 4, 5);
43impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6);
44impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7);
45impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7, 8);
46impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
47impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
48impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
49
50#[cfg(test)]
51mod tests {
52    use crate::{DecodeExt, Encode};
53
54    #[test]
55    fn test_tuple() {
56        let tuple_values = [(1u16, None), (1u16, Some(2u32))];
57        for value in tuple_values {
58            let encoded = value.encode();
59            let decoded = <(u16, Option<u32>)>::decode(encoded).unwrap();
60            assert_eq!(value, decoded);
61        }
62    }
63}