bin_proto/impls/
numerics.rs

1use core::num::{
2    NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU128, NonZeroU16,
3    NonZeroU32, NonZeroU64, NonZeroU8,
4};
5
6use bitstream_io::{BitRead, BitWrite, Endianness};
7
8use crate::{BitDecode, BitEncode, Bits, Result};
9
10impl<Ctx, const C: u32> BitDecode<Ctx, Bits<C>> for bool {
11    fn decode<R, E>(read: &mut R, _: &mut Ctx, _: Bits<C>) -> Result<Self>
12    where
13        R: BitRead,
14        E: Endianness,
15    {
16        if read.read::<C, u8>()? == 0 {
17            Ok(false)
18        } else {
19            Ok(true)
20        }
21    }
22}
23
24impl<Ctx, const C: u32> BitEncode<Ctx, Bits<C>> for bool {
25    fn encode<W, E>(&self, write: &mut W, _: &mut Ctx, _: Bits<C>) -> Result<()>
26    where
27        W: BitWrite,
28        E: Endianness,
29    {
30        write.write::<C, u8>((*self).into())?;
31        Ok(())
32    }
33}
34
35impl<Ctx> BitDecode<Ctx> for bool {
36    fn decode<R, E>(read: &mut R, _: &mut Ctx, (): ()) -> Result<Self>
37    where
38        R: BitRead,
39        E: Endianness,
40    {
41        if read.read_as_to::<E, u8>()? == 0 {
42            Ok(false)
43        } else {
44            Ok(true)
45        }
46    }
47}
48
49impl<Ctx> BitEncode<Ctx> for bool {
50    fn encode<W, E>(&self, write: &mut W, _: &mut Ctx, (): ()) -> Result<()>
51    where
52        W: BitWrite,
53        E: Endianness,
54    {
55        write.write_as_from::<E, _>(u8::from(*self))?;
56        Ok(())
57    }
58}
59
60macro_rules! impl_codec_for_numeric_unordered {
61    ($ty:ty => $data_ty:ty) => {
62        impl<Ctx> $crate::BitDecode<Ctx> for $ty {
63            fn decode<R, E>(read: &mut R, _: &mut Ctx, (): ()) -> $crate::Result<Self>
64            where
65                R: ::bitstream_io::BitRead,
66                E: ::bitstream_io::Endianness,
67            {
68                Ok(::core::convert::TryInto::try_into(
69                    ::bitstream_io::BitRead::read_as_to::<E, $data_ty>(read)?,
70                )?)
71            }
72        }
73
74        impl<Ctx> $crate::BitEncode<Ctx> for $ty {
75            fn encode<W, E>(&self, write: &mut W, _: &mut Ctx, (): ()) -> $crate::Result<()>
76            where
77                W: ::bitstream_io::BitWrite,
78                E: ::bitstream_io::Endianness,
79            {
80                ::bitstream_io::BitWrite::write_as_from::<E, $data_ty>(
81                    write,
82                    ::core::convert::TryInto::try_into(*self)?,
83                )?;
84                Ok(())
85            }
86        }
87    };
88}
89
90macro_rules! impl_codec_for_numeric {
91    ($ty:ty $(: $thru:ident $fallible:tt)? => $data_ty:ty) => {
92        impl<Ctx> $crate::BitDecode<Ctx> for $ty {
93            fn decode<R, E>(
94                read: &mut R,
95                _: &mut Ctx,
96                (): (),
97            ) -> $crate::Result<Self>
98            where
99                R: ::bitstream_io::BitRead,
100                E: ::bitstream_io::Endianness,
101            {
102                Ok(::core::convert::TryInto::try_into(
103                    $(::core::convert::TryInto::<$thru>::try_into)?(
104                        ::bitstream_io::BitRead::read_as_to::<E, $data_ty>(read)?
105                    )$($fallible)?,
106                )?)
107            }
108        }
109
110        impl<Ctx> $crate::BitEncode<Ctx> for $ty {
111            fn encode<W, E>(
112                &self,
113                write: &mut W,
114                _: &mut Ctx,
115                (): (),
116            ) -> $crate::Result<()>
117            where
118                W: ::bitstream_io::BitWrite,
119                E: ::bitstream_io::Endianness
120            {
121                ::bitstream_io::BitWrite::write_as_from::<E, $data_ty>(
122                    write,
123                    ::core::convert::TryInto::try_into(
124                        $(::core::convert::TryInto::<$thru>::try_into)?(*self)$($fallible)?,
125                    )?,
126                )?;
127                Ok(())
128            }
129        }
130    };
131}
132
133macro_rules! impl_bitfield_for_numeric {
134    ($ty:ty $(: $thru:ident $fallible:tt)? => $data_ty:ty) => {
135        impl<Ctx, const C: u32> $crate::BitDecode<Ctx, $crate::Bits<C>> for $ty {
136            fn decode<R, E>(
137                read: &mut R,
138                _: &mut Ctx,
139                _: $crate::Bits<C>,
140            ) -> $crate::Result<Self>
141            where
142                R: ::bitstream_io::BitRead,
143                E: ::bitstream_io::Endianness,
144            {
145                Ok(::core::convert::TryInto::try_into(
146                    $(::core::convert::TryInto::<$thru>::try_into)?(::bitstream_io::BitRead::read::<C, $data_ty>(
147                        read
148                    )$($fallible)?)?,
149                )?)
150            }
151        }
152
153        impl<Ctx, const C: u32> $crate::BitEncode<Ctx, $crate::Bits<C>> for $ty {
154            fn encode<W, E>(
155                &self,
156                write: &mut W,
157                _: &mut Ctx,
158                _: $crate::Bits<C>,
159            ) -> $crate::Result<()>
160            where
161                W: ::bitstream_io::BitWrite,
162                E: ::bitstream_io::Endianness
163            {
164                ::bitstream_io::BitWrite::write::<C, $data_ty>(
165                    write,
166                    ::core::convert::TryInto::try_into(
167                        $(::core::convert::TryInto::<$thru>::try_into)?(*self)$($fallible)?,
168                    )?,
169                )?;
170                Ok(())
171            }
172        }
173    };
174}
175
176impl_codec_for_numeric_unordered!(u8 => u8);
177impl_codec_for_numeric_unordered!(i8 => i8);
178
179impl_codec_for_numeric_unordered!(NonZeroU8 => u8);
180impl_codec_for_numeric_unordered!(NonZeroI8 => i8);
181
182impl_codec_for_numeric!(u16 => u16);
183impl_codec_for_numeric!(i16 => i16);
184impl_codec_for_numeric!(u32 => u32);
185impl_codec_for_numeric!(i32 => i32);
186impl_codec_for_numeric!(u64 => u64);
187impl_codec_for_numeric!(i64 => i64);
188impl_codec_for_numeric!(u128 => u128);
189impl_codec_for_numeric!(i128 => i128);
190
191impl_codec_for_numeric!(NonZeroU16 => u16);
192impl_codec_for_numeric!(NonZeroI16 => i16);
193impl_codec_for_numeric!(NonZeroU32 => u32);
194impl_codec_for_numeric!(NonZeroI32 => i32);
195impl_codec_for_numeric!(NonZeroU64 => u64);
196impl_codec_for_numeric!(NonZeroI64 => i64);
197impl_codec_for_numeric!(NonZeroU128 => u128);
198impl_codec_for_numeric!(NonZeroI128 => i128);
199
200impl_codec_for_numeric!(f32 => f32);
201impl_codec_for_numeric!(f64 => f64);
202
203impl_bitfield_for_numeric!(u8 => u8);
204impl_bitfield_for_numeric!(i8 => i8);
205impl_bitfield_for_numeric!(u16 => u16);
206impl_bitfield_for_numeric!(i16 => i16);
207impl_bitfield_for_numeric!(u32 => u32);
208impl_bitfield_for_numeric!(i32 => i32);
209impl_bitfield_for_numeric!(u64 => u64);
210impl_bitfield_for_numeric!(i64 => i64);
211impl_bitfield_for_numeric!(u128 => u128);
212impl_bitfield_for_numeric!(i128 => i128);
213
214impl_bitfield_for_numeric!(NonZeroU8 => u8);
215impl_bitfield_for_numeric!(NonZeroI8 => i8);
216impl_bitfield_for_numeric!(NonZeroU16 => u16);
217impl_bitfield_for_numeric!(NonZeroI16 => i16);
218impl_bitfield_for_numeric!(NonZeroU32 => u32);
219impl_bitfield_for_numeric!(NonZeroI32 => i32);
220impl_bitfield_for_numeric!(NonZeroU128 => u128);
221impl_bitfield_for_numeric!(NonZeroI128 => i128);
222
223#[cfg(target_pointer_width = "16")]
224mod size {
225    use core::num::{NonZeroIsize, NonZeroUsize};
226
227    impl_codec_for_numeric!(usize => u16);
228    impl_bitfield_for_numeric!(usize => u16);
229
230    impl_codec_for_numeric!(NonZeroUsize: usize? => u16);
231    impl_bitfield_for_numeric!(NonZeroUsize: usize? => u16);
232
233    impl_codec_for_numeric!(isize => i16);
234    impl_bitfield_for_numeric!(isize => i16);
235
236    impl_codec_for_numeric!(NonZeroIsize: isize? => i16);
237    impl_bitfield_for_numeric!(NonZeroIsize: isize? => i16);
238}
239
240#[cfg(target_pointer_width = "32")]
241mod size {
242    use core::num::{NonZeroIsize, NonZeroUsize};
243
244    impl_codec_for_numeric!(usize => u32);
245    impl_bitfield_for_numeric!(usize => u32);
246
247    impl_codec_for_numeric!(NonZeroUsize: usize? => u32);
248    impl_bitfield_for_numeric!(NonZeroUsize: usize? => u32);
249
250    impl_codec_for_numeric!(isize => i32);
251    impl_bitfield_for_numeric!(isize => i32);
252
253    impl_codec_for_numeric!(NonZeroIsize: isize? => i32);
254    impl_bitfield_for_numeric!(NonZeroIsize: isize? => i32);
255}
256
257#[cfg(target_pointer_width = "64")]
258mod size {
259    use core::num::{NonZeroIsize, NonZeroUsize};
260
261    impl_codec_for_numeric!(usize => u64);
262    impl_bitfield_for_numeric!(usize => u64);
263
264    impl_codec_for_numeric!(NonZeroUsize: usize? => u64);
265    impl_bitfield_for_numeric!(NonZeroUsize: usize? => u64);
266
267    impl_codec_for_numeric!(isize => i64);
268    impl_bitfield_for_numeric!(isize => i64);
269
270    impl_codec_for_numeric!(NonZeroIsize: isize? => i64);
271    impl_bitfield_for_numeric!(NonZeroIsize: isize? => i64);
272}