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
72impl<W> Encode<W> for isize
73where
74 W: IoWrite,
75{
76 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
77 match i64::try_from(*self) {
78 Ok(i64_int) => i64_int.encode(writer),
79 Err(_) => Err(Error::InvalidFormat),
80 }
81 }
82}
83
84impl<W> Encode<W> for i128
85where
86 W: IoWrite,
87{
88 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
89 match i64::try_from(*self) {
90 Ok(i64_int) => i64_int.encode(writer),
91 Err(_) => Err(Error::InvalidFormat),
92 }
93 }
94}
95
96macro_rules! impl_encode_int {
97 ($ty:ty, $format:expr, $size:expr) => {
98 impl<W> Encode<W> for $ty
99 where
100 W: IoWrite,
101 {
102 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
103 writer.write(&$format.as_slice())?;
104 writer.write(&self.to_be_bytes())?;
105 Ok($size)
106 }
107 }
108 };
109}
110impl_encode_int!(u16, Format::Uint16, 3);
111impl_encode_int!(u32, Format::Uint32, 5);
112impl_encode_int!(u64, Format::Uint64, 9);
113impl_encode_int!(i16, Format::Int16, 3);
114impl_encode_int!(i32, Format::Int32, 5);
115impl_encode_int!(i64, Format::Int64, 9);
116
117macro_rules! impl_nonzero_int {
118 ($ty:ty) => {
119 impl<W> Encode<W> for $ty
120 where
121 W: IoWrite,
122 {
123 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
124 self.get().encode(writer)
125 }
126 }
127 };
128}
129impl_nonzero_int!(core::num::NonZeroU8);
130impl_nonzero_int!(core::num::NonZeroU16);
131impl_nonzero_int!(core::num::NonZeroU32);
132impl_nonzero_int!(core::num::NonZeroU64);
133impl_nonzero_int!(core::num::NonZeroUsize);
134impl_nonzero_int!(core::num::NonZeroI8);
135impl_nonzero_int!(core::num::NonZeroI16);
136impl_nonzero_int!(core::num::NonZeroI32);
137impl_nonzero_int!(core::num::NonZeroI64);
138impl_nonzero_int!(core::num::NonZeroIsize);
139
140macro_rules! impl_atomic_int {
141 ($ty:ty, $bits:literal) => {
142 #[cfg(target_has_atomic = $bits)]
143 impl<W> Encode<W> for $ty
144 where
145 W: IoWrite,
146 {
147 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
148 self.load(core::sync::atomic::Ordering::Relaxed)
149 .encode(writer)
150 }
151 }
152 };
153}
154impl_atomic_int!(core::sync::atomic::AtomicU8, "8");
155impl_atomic_int!(core::sync::atomic::AtomicU16, "16");
156impl_atomic_int!(core::sync::atomic::AtomicU32, "32");
157impl_atomic_int!(core::sync::atomic::AtomicU64, "64");
158impl_atomic_int!(core::sync::atomic::AtomicUsize, "ptr");
159impl_atomic_int!(core::sync::atomic::AtomicI8, "8");
160impl_atomic_int!(core::sync::atomic::AtomicI16, "16");
161impl_atomic_int!(core::sync::atomic::AtomicI32, "32");
162impl_atomic_int!(core::sync::atomic::AtomicI64, "64");
163impl_atomic_int!(core::sync::atomic::AtomicIsize, "ptr");
164
165#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
167pub struct EncodeMinimizeInt<N>(pub N);
168
169impl<W, N> Encode<W> for EncodeMinimizeInt<N>
170where
171 W: IoWrite,
172 N: ToPrimitive,
173{
174 fn encode(&self, writer: &mut W) -> Result<usize, W::Error> {
175 let n = &self.0;
176 if let Some(v) = n.to_u8() {
177 v.encode(writer)
178 } else if let Some(v) = n.to_i8() {
179 v.encode(writer)
180 } else if let Some(v) = n.to_u16() {
181 v.encode(writer)
182 } else if let Some(v) = n.to_i16() {
183 v.encode(writer)
184 } else if let Some(v) = n.to_u32() {
185 v.encode(writer)
186 } else if let Some(v) = n.to_i32() {
187 v.encode(writer)
188 } else if let Some(v) = n.to_u64() {
189 v.encode(writer)
190 } else if let Some(v) = n.to_i64() {
191 v.encode(writer)
192 } else {
193 Err(Error::InvalidFormat)
194 }
195 }
196}
197
198#[cfg(test)]
199mod tests {
200 use super::*;
201 use rstest::rstest;
202
203 #[rstest]
204 #[case(u8::MIN,[0x00])]
205 #[case(0x7f_u8,[0x7f])]
206 #[case(0x80_u8,[Format::Uint8.as_byte(), 0x80])]
207 #[case(u8::MAX,[Format::Uint8.as_byte(), 0xff])]
208 fn encode_uint8<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
209 #[case] value: V,
210 #[case] expected: E,
211 ) {
212 let expected = expected.as_ref();
213
214 let mut buf: Vec<u8> = vec![];
215 let n = value.encode(&mut buf).unwrap();
216 assert_eq!(buf, expected);
217 assert_eq!(n, expected.len());
218 }
219
220 #[rstest]
221 #[case(u16::MIN,[Format::Uint16.as_byte(),0x00,0x00])]
222 #[case(0x00ff_u16,[Format::Uint16.as_byte(),0x00,0xff])]
223 #[case(0x01ff_u16, [Format::Uint16.as_byte(), 0x01, 0xff])]
224 #[case(u16::MAX, [Format::Uint16.as_byte(), 0xff, 0xff])]
225 fn encode_uint16<V: Encode<Vec<u8>>, E: AsRef<[u8]>>(#[case] value: V, #[case] expected: E) {
226 let expected = expected.as_ref();
227
228 let mut buf = vec![];
229 let n = value.encode(&mut buf).unwrap();
230 assert_eq!(buf, expected);
231 assert_eq!(n, expected.len());
232 }
233
234 #[rstest]
235 #[case(u32::MIN, [Format::Uint32.as_byte(), 0x00, 0x00,0x00, 0x00])]
236 #[case(0x0000ffff_u32, [Format::Uint32.as_byte(), 0x00, 0x00,0xff, 0xff])]
237 #[case(0x0001ffff_u32, [Format::Uint32.as_byte(), 0x00, 0x01,0xff, 0xff])]
238 #[case(u32::MAX, [Format::Uint32.as_byte(),0xff, 0xff, 0xff,0xff])]
239 fn encode_uint32<V: Encode<Vec<u8>>, E: AsRef<[u8]>>(#[case] value: V, #[case] expected: E) {
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(u64::MIN, [Format::Uint64.as_byte(), 0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00])]
250 #[case(u64::MAX, [Format::Uint64.as_byte(), 0xff, 0xff, 0xff,0xff,0xff, 0xff, 0xff,0xff])]
251 fn encode_uint64<V: Encode<Vec<u8>>, E: AsRef<[u8]>>(#[case] value: V, #[case] expected: E) {
252 let expected = expected.as_ref();
253
254 let mut buf = vec![];
255 let n = value.encode(&mut buf).unwrap();
256 assert_eq!(buf, expected);
257 assert_eq!(n, expected.len());
258 }
259
260 #[rstest]
261 #[case(i8::MIN,[Format::Int8.as_byte(),0x80])]
262 #[case(-32_i8,[0xe0])]
263 #[case(-1_i8,[0xff])]
264 #[case(0_i8,[Format::Int8.as_byte(),0x00])]
265 #[case(i8::MAX,[Format::Int8.as_byte(),0x7f])]
266 fn encode_int8<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
267 #[case] value: V,
268 #[case] expected: E,
269 ) {
270 let expected = expected.as_ref();
271
272 let mut buf = vec![];
273 let n = value.encode(&mut buf).unwrap();
274 assert_eq!(buf, expected);
275 assert_eq!(n, expected.len());
276 }
277
278 #[rstest]
279 #[case(i16::MIN,[Format::Int16.as_byte(),0x80,0x00])]
280 #[case(-1_i16,[Format::Int16.as_byte(),0xff,0xff])]
281 #[case(0_i16,[Format::Int16.as_byte(),0x00,0x00])]
282 #[case(i16::MAX,[Format::Int16.as_byte(),0x7f,0xff])]
283 fn encode_int16<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
284 #[case] value: V,
285 #[case] expected: E,
286 ) {
287 let expected = expected.as_ref();
288
289 let mut buf = vec![];
290 let n = value.encode(&mut buf).unwrap();
291 assert_eq!(buf, expected);
292 assert_eq!(n, expected.len());
293 }
294
295 #[rstest]
296 #[case(i32::MIN,[Format::Int32.as_byte(),0x80,0x00,0x00,0x00])]
297 #[case(-1_i32,[Format::Int32.as_byte(),0xff,0xff,0xff,0xff])]
298 #[case(0_i32,[Format::Int32.as_byte(),0x00,0x00,0x00,0x00])]
299 #[case(i32::MAX,[Format::Int32.as_byte(),0x7f,0xff,0xff,0xff])]
300 fn encode_int32<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
301 #[case] value: V,
302 #[case] expected: E,
303 ) {
304 let expected = expected.as_ref();
305
306 let mut buf = vec![];
307 let n = value.encode(&mut buf).unwrap();
308 assert_eq!(buf, expected);
309 assert_eq!(n, expected.len());
310 }
311
312 #[rstest]
313 #[case(i64::MIN,[Format::Int64.as_byte(),0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00])]
314 #[case(-1_i64,[Format::Int64.as_byte(),0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff])]
315 #[case(0_i64,[Format::Int64.as_byte(),0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])]
316 #[case(i64::MAX,[Format::Int64.as_byte(),0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff])]
317 fn encode_int64<V: Encode<Vec<u8>>, E: AsRef<[u8]> + Sized>(
318 #[case] value: V,
319 #[case] expected: E,
320 ) {
321 let expected = expected.as_ref();
322
323 let mut buf = vec![];
324 let n = value.encode(&mut buf).unwrap();
325 assert_eq!(buf, expected);
326 assert_eq!(n, expected.len());
327 }
328
329 #[rstest]
330 #[case(0_i8,[0x00])]
331 #[case(0x7f_i8,[0x7f])]
332 #[case(0_u16,[0x00])]
333 #[case(0x7f_u16,[0x7f])]
334 #[case(0x80_u16,[Format::Uint8.as_byte(),0x80])]
335 #[case(0_i16,[0x00])]
336 #[case(0x7f_i16,[0x7f])]
337 #[case(0_u32,[0x00])]
338 #[case(0_u64,[0x00])]
339 #[case(0_u128,[0x00])]
340 #[case(0_i32,[0x00])]
341 #[case(0_i64,[0x00])]
342 #[case(0_i128,[0x00])]
343 #[case(3.0_f32,[0x03])]
344 fn encode_int_minimize<V: ToPrimitive, E: AsRef<[u8]> + Sized>(
345 #[case] value: V,
346 #[case] expected: E,
347 ) {
348 let expected = expected.as_ref();
349 let encoder = EncodeMinimizeInt(value);
350
351 let mut buf = vec![];
352 let n = encoder.encode(&mut buf).unwrap();
353 assert_eq!(buf, expected);
354 assert_eq!(n, expected.len());
355 }
356}