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