1use crate::Result;
4
5pub trait Read: Sized {
7 fn read<T: crate::tape::Read>(_: &mut T) -> Result<Self>;
9}
10
11pub trait Write {
13 fn write<T: crate::tape::Write>(&self, _: &mut T) -> Result<()>;
15}
16
17macro_rules! read {
18 ($tape:ident, $size:expr) => {{
19 let mut buffer: [u8; $size] = [0; $size];
20 std::io::Read::read_exact($tape, &mut buffer)?;
21 buffer
22 }};
23}
24
25macro_rules! implement {
26 ([i8; 4]) => {
27 impl Read for [i8; 4] {
28 #[inline]
29 fn read<T: crate::tape::Read>(tape: &mut T) -> Result<Self> {
30 let value = read!(tape, 4);
31 Ok([
32 value[0] as i8,
33 value[1] as i8,
34 value[2] as i8,
35 value[3] as i8,
36 ])
37 }
38 }
39
40 impl Write for [i8; 4] {
41 #[inline]
42 fn write<T: crate::tape::Write>(&self, tape: &mut T) -> Result<()> {
43 tape.give(&[self[0] as u8, self[1] as u8, self[2] as u8, self[3] as u8])
44 }
45 }
46 };
47 ([u8; $count:expr]) => {
48 impl Read for [u8; $count] {
49 #[inline]
50 fn read<T: crate::tape::Read>(tape: &mut T) -> Result<Self> {
51 Ok(read!(tape, $count))
52 }
53 }
54
55 impl Write for [u8; $count] {
56 #[inline]
57 fn write<T: crate::tape::Write>(&self, tape: &mut T) -> Result<()> {
58 tape.write_all(self)
59 }
60 }
61 };
62 ($type:ident, $size:expr) => {
63 impl Read for $type {
64 #[inline]
65 fn read<T: crate::tape::Read>(tape: &mut T) -> Result<Self> {
66 Ok($type::from_be_bytes(read!(tape, $size)))
67 }
68 }
69
70 impl Write for $type {
71 #[inline]
72 fn write<T: crate::tape::Write>(&self, tape: &mut T) -> Result<()> {
73 let value = self.to_be_bytes();
74 tape.write_all(&value)
75 }
76 }
77 };
78}
79
80implement!(i8, 1);
81implement!(u8, 1);
82implement!(i16, 2);
83implement!(u16, 2);
84implement!(i32, 4);
85implement!(i64, 8);
86implement!(u32, 4);
87implement!([i8; 4]);
88implement!([u8; 3]);
89implement!([u8; 4]);
90implement!([u8; 10]);
91
92macro_rules! implement {
93 ($($type:ident),*) => {
94 impl<$($type),*> Read for ($($type),*)
95 where
96 $($type: Read,)*
97 {
98 #[inline]
99 fn read<T: crate::tape::Read>(tape: &mut T) -> Result<Self> {
100 Ok(($(tape.take::<$type>()?),*))
101 }
102 }
103 };
104}
105
106implement!(U, V);
107
108impl<U: Write> Write for [U] {
109 fn write<T: crate::tape::Write>(&self, tape: &mut T) -> Result<()> {
110 for value in self.iter() {
111 tape.give(value)?;
112 }
113 Ok(())
114 }
115}