1use std::{error::Error, io};
8
9use crate::bits::{ReadBits, WriteBits};
10
11pub trait ByteArray: AsRef<[u8]> + AsMut<[u8]> + Send + Sync + 'static {
15 fn zeroed() -> Self;
17}
18
19impl<const N: usize> ByteArray for [u8; N] {
20 #[inline]
21 fn zeroed() -> Self {
22 [0u8; N]
23 }
24}
25
26pub trait FixedCode: Sized {
28 const SIZE: usize;
29 type Array: ByteArray;
30 type Error: Error + Send + Sync + 'static;
31 fn fix_encode(&self) -> Self::Array;
32 fn fix_decode(input: &Self::Array) -> Result<Self, Self::Error>;
33
34 #[inline]
36 fn fix_write(&self, write: &mut impl io::Write) -> io::Result<()> {
37 io::Write::write_all(write, self.fix_encode().as_ref())
38 }
39
40 #[inline]
42 fn fix_read(read: &mut impl io::Read) -> io::Result<Self> {
43 let mut buffer = Self::Array::zeroed();
44 io::Read::read_exact(read, buffer.as_mut())?;
45 Self::fix_decode(&buffer).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
46 }
47}
48
49impl<const N: usize> FixedCode for [u8; N]
50where
51 [u8; N]: ByteArray,
52{
53 const SIZE: usize = N;
54 type Array = [u8; N];
55 type Error = std::convert::Infallible;
56
57 #[inline]
58 fn fix_encode(&self) -> Self {
59 *self
60 }
61
62 #[inline]
63 fn fix_decode(input: &Self) -> Result<Self, Self::Error> {
64 Ok(*input)
65 }
66}
67
68macro_rules! impl_fixedcode_le_bytes {
69 ($($t:ty),* $(,)?) => {
70 $(
71 impl $crate::encode::FixedCode for $t {
72 const SIZE: usize = std::mem::size_of::<Self>();
73 type Array = [u8; Self::SIZE];
74 type Error = std::convert::Infallible;
75
76 fn fix_encode(&self) -> Self::Array {
77 self.to_le_bytes()
78 }
79
80 fn fix_decode(input: &Self::Array) -> Result<Self, Self::Error> {
81 Ok(Self::from_le_bytes(*input))
82 }
83 }
84 )*
85 };
86}
87
88impl_fixedcode_le_bytes!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, f32, f64);
89
90macro_rules! impl_fixedcode_tuple {
91 () => {
92 impl VarCode for () {
93 fn var_bit_len(&self) -> usize {
94 0
95 }
96
97 fn var_write(&self, _write: &mut WriteBits<impl io::Write>) -> io::Result<()> {
98 Ok(())
99 }
100
101 fn var_read(_read: &mut ReadBits<impl io::Read>) -> io::Result<Self> {
102 Ok(())
103 }
104 }
105 };
106 ($($a:ident)+) => {
107 #[allow(non_snake_case)]
108 impl<$($a),*> VarCode for ($($a,)*)
109 where
110 $($a: VarCode),*
111 {
112 fn var_bit_len(&self) -> usize {
113
114 let ($($a,)*) = self;
115 0 $(+ $a.var_bit_len())*
116 }
117
118 fn var_write(&self, write: &mut WriteBits<impl io::Write>) -> io::Result<()> {
119 let ($($a,)*) = self;
120 $(
121 $a.var_write(write)?;
122 )*
123 Ok(())
124 }
125
126 fn var_read(read: &mut ReadBits<impl io::Read>) -> io::Result<Self> {
127 Ok((
128 $(
129 $a::var_read(read)?,
130 )*
131 ))
132 }
133 }
134 };
135}
136
137for_tuple!(impl_fixedcode_tuple);
138
139pub trait VarCode {
145 fn var_bit_len(&self) -> usize;
146 fn var_write(&self, write: &mut WriteBits<impl io::Write>) -> io::Result<()>;
147 fn var_read(read: &mut ReadBits<impl io::Read>) -> io::Result<Self>
148 where
149 Self: Sized;
150}
151
152impl<T> VarCode for T
153where
154 T: FixedCode,
155{
156 fn var_bit_len(&self) -> usize {
157 Self::SIZE * 8
158 }
159
160 #[inline]
161 fn var_write(&self, write: &mut WriteBits<impl io::Write>) -> io::Result<()> {
162 FixedCode::fix_write(self, write)
163 }
164
165 #[inline]
166 fn var_read(read: &mut ReadBits<impl io::Read>) -> io::Result<T>
167 where
168 Self: Sized,
169 {
170 FixedCode::fix_read(read)
171 }
172}