typeface/
value.rs

1//! Types that can be read and written.
2
3use crate::Result;
4
5/// A type that can be read.
6pub trait Read: Sized {
7    /// Read a value.
8    fn read<T: crate::tape::Read>(_: &mut T) -> Result<Self>;
9}
10
11/// A type that can be written.
12pub trait Write {
13    /// Write the value.
14    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}