1use num_traits::ToPrimitive;
2
3use super::{Encode, Error, Result};
4use crate::{formats::Format, io::IoWrite};
5
6impl<W> Encode<W> for u8
7where
8 W: IoWrite,
9{
10 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
11 match self {
12 0x00..=0x7f => {
13 writer.write_bytes(&Format::PositiveFixInt(*self).as_slice())?;
14
15 Ok(1)
16 }
17 _ => {
18 writer.write_bytes(&Format::Uint8.as_slice())?;
19 writer.write_bytes(&self.to_be_bytes())?;
20 Ok(2)
21 }
22 }
23 }
24}
25
26impl<W> Encode<W> for u128
27where
28 W: IoWrite,
29{
30 fn encode(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
31 match u64::try_from(*self) {
32 Ok(u64_uint) => u64_uint.encode(writer),
33 Err(_) => Err(Error::InvalidFormat),
34 }
35 }
36}
37
38impl<W> Encode<W> for i8
39where
40 W: IoWrite,
41{
42 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
43 match self {
44 -32..=-1 => {
45 writer.write_bytes(&Format::NegativeFixInt(*self).as_slice())?;
46 Ok(1)
47 }
48 _ => {
49 writer.write_bytes(&Format::Int8.as_slice())?;
50 writer.write_bytes(&self.to_be_bytes())?;
51
52 Ok(2)
53 }
54 }
55 }
56}
57
58macro_rules! impl_encode_int {
59 ($ty:ty, $format:expr, $size:expr) => {
60 impl<W> Encode<W> for $ty
61 where
62 W: IoWrite,
63 {
64 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
65 writer.write_bytes(&$format.as_slice())?;
66 writer.write_bytes(&self.to_be_bytes())?;
67 Ok($size)
68 }
69 }
70 };
71}
72impl_encode_int!(u16, Format::Uint16, 3);
73impl_encode_int!(u32, Format::Uint32, 5);
74impl_encode_int!(u64, Format::Uint64, 9);
75impl_encode_int!(i16, Format::Int16, 3);
76impl_encode_int!(i32, Format::Int32, 5);
77impl_encode_int!(i64, Format::Int64, 9);
78
79impl<W> Encode<W> for i128
80where
81 W: IoWrite,
82{
83 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
84 match i64::try_from(*self) {
85 Ok(i64_int) => i64_int.encode(writer),
86 Err(_) => Err(Error::InvalidFormat),
87 }
88 }
89}
90
91#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
93pub struct EncodeMinimizeInt<N>(pub N);
94
95impl<W, N> Encode<W> for EncodeMinimizeInt<N>
96where
97 W: IoWrite,
98 N: ToPrimitive,
99{
100 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
101 let n = &self.0;
102 if let Some(v) = n.to_u8() {
103 v.encode(writer)
104 } else if let Some(v) = n.to_i8() {
105 v.encode(writer)
106 } else if let Some(v) = n.to_u16() {
107 v.encode(writer)
108 } else if let Some(v) = n.to_i16() {
109 v.encode(writer)
110 } else if let Some(v) = n.to_u32() {
111 v.encode(writer)
112 } else if let Some(v) = n.to_i32() {
113 v.encode(writer)
114 } else if let Some(v) = n.to_u64() {
115 v.encode(writer)
116 } else if let Some(v) = n.to_i64() {
117 v.encode(writer)
118 } else {
119 Err(Error::InvalidFormat)
120 }
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127 use rstest::rstest;
128
129 #[rstest]
130 #[case(u8::MIN,[0x00])]
131 #[case(0x7f_u8,[0x7f])]
132 #[case(0x80_u8,[Format::Uint8.as_byte(), 0x80])]
133 #[case(u8::MAX,[Format::Uint8.as_byte(), 0xff])]
134 fn encode_uint8<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
135 #[case] value: V,
136 #[case] expected: E,
137 ) {
138 let expected = expected.as_ref();
139
140 let mut buf: Vec<u8> = vec![];
141 let n = value.encode(&mut buf).unwrap();
142 assert_eq!(buf, expected);
143 assert_eq!(n, expected.len());
144 }
145
146 #[rstest]
147 #[case(u16::MIN,[Format::Uint16.as_byte(),0x00,0x00])]
148 #[case(0x00ff_u16,[Format::Uint16.as_byte(),0x00,0xff])]
149 #[case(0x01ff_u16, [Format::Uint16.as_byte(), 0x01, 0xff])]
150 #[case(u16::MAX, [Format::Uint16.as_byte(), 0xff, 0xff])]
151 fn encode_uint16<V: Encode<Vec<u8>>, E: AsRef<[u8]>>(#[case] value: V, #[case] expected: E) {
152 let expected = expected.as_ref();
153
154 let mut buf = vec![];
155 let n = value.encode(&mut buf).unwrap();
156 assert_eq!(buf, expected);
157 assert_eq!(n, expected.len());
158 }
159
160 #[rstest]
161 #[case(u32::MIN, [Format::Uint32.as_byte(), 0x00, 0x00,0x00, 0x00])]
162 #[case(0x0000ffff_u32, [Format::Uint32.as_byte(), 0x00, 0x00,0xff, 0xff])]
163 #[case(0x0001ffff_u32, [Format::Uint32.as_byte(), 0x00, 0x01,0xff, 0xff])]
164 #[case(u32::MAX, [Format::Uint32.as_byte(),0xff, 0xff, 0xff,0xff])]
165 fn encode_uint32<V: Encode<Vec<u8>>, E: AsRef<[u8]>>(#[case] value: V, #[case] expected: E) {
166 let expected = expected.as_ref();
167
168 let mut buf = vec![];
169 let n = value.encode(&mut buf).unwrap();
170 assert_eq!(buf, expected);
171 assert_eq!(n, expected.len());
172 }
173
174 #[rstest]
175 #[case(u64::MIN, [Format::Uint64.as_byte(), 0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00])]
176 #[case(u64::MAX, [Format::Uint64.as_byte(), 0xff, 0xff, 0xff,0xff,0xff, 0xff, 0xff,0xff])]
177 fn encode_uint64<V: Encode<Vec<u8>>, E: AsRef<[u8]>>(#[case] value: V, #[case] expected: E) {
178 let expected = expected.as_ref();
179
180 let mut buf = vec![];
181 let n = value.encode(&mut buf).unwrap();
182 assert_eq!(buf, expected);
183 assert_eq!(n, expected.len());
184 }
185
186 #[rstest]
187 #[case(i8::MIN,[Format::Int8.as_byte(),0x80])]
188 #[case(-32_i8,[0xe0])]
189 #[case(-1_i8,[0xff])]
190 #[case(0_i8,[Format::Int8.as_byte(),0x00])]
191 #[case(i8::MAX,[Format::Int8.as_byte(),0x7f])]
192 fn encode_int8<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
193 #[case] value: V,
194 #[case] expected: E,
195 ) {
196 let expected = expected.as_ref();
197
198 let mut buf = vec![];
199 let n = value.encode(&mut buf).unwrap();
200 assert_eq!(buf, expected);
201 assert_eq!(n, expected.len());
202 }
203
204 #[rstest]
205 #[case(i16::MIN,[Format::Int16.as_byte(),0x80,0x00])]
206 #[case(-1_i16,[Format::Int16.as_byte(),0xff,0xff])]
207 #[case(0_i16,[Format::Int16.as_byte(),0x00,0x00])]
208 #[case(i16::MAX,[Format::Int16.as_byte(),0x7f,0xff])]
209 fn encode_int16<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
210 #[case] value: V,
211 #[case] expected: E,
212 ) {
213 let expected = expected.as_ref();
214
215 let mut buf = vec![];
216 let n = value.encode(&mut buf).unwrap();
217 assert_eq!(buf, expected);
218 assert_eq!(n, expected.len());
219 }
220
221 #[rstest]
222 #[case(i32::MIN,[Format::Int32.as_byte(),0x80,0x00,0x00,0x00])]
223 #[case(-1_i32,[Format::Int32.as_byte(),0xff,0xff,0xff,0xff])]
224 #[case(0_i32,[Format::Int32.as_byte(),0x00,0x00,0x00,0x00])]
225 #[case(i32::MAX,[Format::Int32.as_byte(),0x7f,0xff,0xff,0xff])]
226 fn encode_int32<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
227 #[case] value: V,
228 #[case] expected: E,
229 ) {
230 let expected = expected.as_ref();
231
232 let mut buf = vec![];
233 let n = value.encode(&mut buf).unwrap();
234 assert_eq!(buf, expected);
235 assert_eq!(n, expected.len());
236 }
237
238 #[rstest]
239 #[case(i64::MIN,[Format::Int64.as_byte(),0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00])]
240 #[case(-1_i64,[Format::Int64.as_byte(),0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff])]
241 #[case(0_i64,[Format::Int64.as_byte(),0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])]
242 #[case(i64::MAX,[Format::Int64.as_byte(),0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff])]
243 fn encode_int64<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
244 #[case] value: V,
245 #[case] expected: E,
246 ) {
247 let expected = expected.as_ref();
248
249 let mut buf = vec![];
250 let n = value.encode(&mut buf).unwrap();
251 assert_eq!(buf, expected);
252 assert_eq!(n, expected.len());
253 }
254
255 #[rstest]
256 #[case(0_i8,[0x00])]
257 #[case(0x7f_i8,[0x7f])]
258 #[case(0_u16,[0x00])]
259 #[case(0x7f_u16,[0x7f])]
260 #[case(0x80_u16,[Format::Uint8.as_byte(),0x80])]
261 #[case(0_i16,[0x00])]
262 #[case(0x7f_i16,[0x7f])]
263 #[case(0_u32,[0x00])]
264 #[case(0_u64,[0x00])]
265 #[case(0_u128,[0x00])]
266 #[case(0_i32,[0x00])]
267 #[case(0_i64,[0x00])]
268 #[case(0_i128,[0x00])]
269 #[case(3.0_f32,[0x03])]
270 fn encode_int_minimize<V: ToPrimitive, E: AsRef<[u8]> + Sized>(
271 #[case] value: V,
272 #[case] expected: E,
273 ) {
274 let expected = expected.as_ref();
275 let encoder = EncodeMinimizeInt(value);
276
277 let mut buf = vec![];
278 let n = encoder.encode(&mut buf).unwrap();
279 assert_eq!(buf, expected);
280 assert_eq!(n, expected.len());
281 }
282}