1use std::io::{Read, Write};
2
3use super::{DataFormat, DataReadError, DataWriteError};
4
5macro_rules! impl_tuple_dataformat {
6 ($($name:ident),+) => {
7 impl<$($name: DataFormat),+> DataFormat for ($($name,)+) {
8 type Header = ($($name::Header,)+);
9 const LATEST_HEADER: Self::Header = ($($name::LATEST_HEADER,)+);
11
12 paste::paste! {
13 fn write_header<W: Write>(&self, writer: &mut W) -> Result<usize, DataWriteError> {
14 let ($([<$name:lower>],)+) = self;
15 let mut written = 0;
16 $(written += [<$name:lower>].write_header(writer)?;)+
17 Ok(written)
18 }
19
20 fn read_header<R: Read>(reader: &mut R) -> Result<Self::Header, DataReadError> {
21 Ok(($($name::read_header(reader)?,)+))
22 }
23
24 fn write_data<W: Write>(&self, writer: &mut W) -> Result<usize, DataWriteError>{
25 let ($([<$name:lower>],)+) = self;
26 let mut written = 0;
27 $(written += [<$name:lower>].write_data(writer)?;)+
28 Ok(written)
29 }
30
31 fn read_data<R: Read>(reader: &mut R, header: &Self::Header) -> Result<Self, DataReadError> {
32 let ($([<$name:lower>],)+) = header;
33 Ok(($($name::read_data(reader, [<$name:lower>])?,)+))
34 }
35
36 }
37 }
38 };
39}
40
41impl_tuple_dataformat!(A, B);
42impl_tuple_dataformat!(A, B, C);
43
44impl DataFormat for () {
45 type Header = ();
46 const LATEST_HEADER: Self::Header = ();
47
48 fn write_header<W: Write>(&self, _writer: &mut W) -> Result<usize, DataWriteError> {
49 Ok(0)
50 }
51
52 fn read_header<R: Read>(_reader: &mut R) -> Result<Self::Header, DataReadError> {
53 Ok(())
54 }
55
56 fn write_data<W: Write>(&self, _writer: &mut W) -> Result<usize, DataWriteError> {
57 Ok(0)
58 }
59
60 fn read_data<R: Read>(_reader: &mut R, _header: &Self::Header) -> Result<Self, DataReadError> {
61 Ok(())
62 }
63}
64
65#[cfg(test)]
66#[rustfmt::skip]
67mod test {
68 use crate::format::DataFormat;
69
70 macro_rules! case {
71 ($name:ident, $ty:ty, $a:expr, $b:expr) => {
72 #[test]
73 fn $name() {
74 let mut data = Vec::new();
75 $a.write_data(&mut data).unwrap();
76 assert_eq!(data, &$b);
77
78 let mut reader = &data[..];
79 let read_value = <$ty>::read_data(&mut reader, &<$ty as DataFormat>::LATEST_HEADER).unwrap();
80 assert_eq!(read_value, $a);
81
82 }
83
84 };
85 }
86
87 case!(test_tuple_0, (), (), [0u8; 0]);
88 case!(test_tuple_2, (u8, u16), (1u8, 2u16), [1, 2, 0]);
89 case!(test_tuple_3, (u8, u16, u32), (1u8, 2u16, 3u32), [
90 1,
91 2, 0,
92 3, 0, 0, 0
93 ]);
94 case!(test_tuple_2_1, ((u8, u16), u32), ((1u8, 2u16), 3u32), [
95 1,
96 2, 0,
97 3, 0, 0, 0
98 ]);
99 case!(test_tuple_2_2, ((u8, u16), (u32, u64)), ((1u8, 2u16), (3u32, 4u64)), [
100 1,
101 2, 0,
102 3, 0, 0, 0,
103 4, 0, 0, 0, 0, 0, 0, 0
104 ]);
105 case!(test_tuple_2_rev, (u16, u8), (2u16, 1u8), [2, 0, 1]);
106 case!(test_tuple_2_1_rev, (u32, (u16, u8)), (3u32, (2u16, 1u8)), [
107 3, 0, 0, 0,
108 2, 0,
109 1
110 ]);
111 case!(test_tuple_2_2_rev, ((u32, u64), (u16, u8)), ((3u32, 4u64), (2u16, 1u8)), [
112 3, 0, 0, 0,
113 4, 0, 0, 0, 0, 0, 0, 0,
114 2,
115 0, 1
116 ]);
117
118}