1use crate::{EncodeSize, Error, Read, Write};
4use bytes::{Buf, BufMut};
5use paste::paste;
6
7macro_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 <$( [<T $index>]: Read ),*> Read for ( $( [<T $index>], )* ) {
27 type Cfg = ( $( [<T $index>]::Cfg, )* );
28 #[inline]
29 fn read_cfg(buf: &mut impl Buf, cfg: &Self::Cfg) -> Result<Self, Error> {
30 Ok(( $( [<T $index>]::read_cfg(buf, &cfg.$index)?, )* ))
31 }
32 }
33 }
34 };
35}
36
37impl_codec_for_tuple!(0);
39impl_codec_for_tuple!(0, 1);
40impl_codec_for_tuple!(0, 1, 2);
41impl_codec_for_tuple!(0, 1, 2, 3);
42impl_codec_for_tuple!(0, 1, 2, 3, 4);
43impl_codec_for_tuple!(0, 1, 2, 3, 4, 5);
44impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6);
45impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7);
46impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7, 8);
47impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
48impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
49impl_codec_for_tuple!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
50
51#[cfg(test)]
52mod tests {
53 use crate::{DecodeExt, Encode};
54
55 #[test]
56 fn test_tuple() {
57 let tuple_values = [(1u16, None), (1u16, Some(2u32))];
58 for value in tuple_values {
59 let encoded = value.encode();
60 let decoded = <(u16, Option<u32>)>::decode(encoded).unwrap();
61 assert_eq!(value, decoded);
62 }
63 }
64
65 #[test]
66 fn test_conformity() {
67 let t1 = (true, 0x42u8);
68 assert_eq!(t1.encode(), &[0x01, 0x42][..]);
69
70 let t2 = (0xABCDu16, false, 0xDEADBEEFu32);
71 assert_eq!(t2.encode(), &[0xAB, 0xCD, 0x00, 0xDE, 0xAD, 0xBE, 0xEF][..]);
72
73 let t3 = ((0x01u8, 0x02u8), 0x03u8); assert_eq!(t3.encode(), &[0x01, 0x02, 0x03][..]);
75
76 let t_option_some = (Some(0x1234u16), 0xFFu8);
77 assert_eq!(t_option_some.encode(), &[0x01, 0x12, 0x34, 0xFF][..]);
81
82 let t_option_none = (0xFFu8, Option::<u16>::None);
83 assert_eq!(t_option_none.encode(), &[0xFF, 0x00][..]);
86 }
87}