binary_util/
types.rs

1use core::fmt;
2
3macro_rules! impl_type {
4    (
5        $ty: ty, $for_ty: ty
6    ) => {
7        impl From<$ty> for $for_ty {
8            fn from(val: $ty) -> Self {
9                val.0
10            }
11        }
12
13        impl From<$for_ty> for $ty {
14            fn from(val: $for_ty) -> Self {
15                Self::new(val)
16            }
17        }
18
19        impl std::ops::Deref for $ty {
20            type Target = $for_ty;
21
22            fn deref(&self) -> &Self::Target {
23                &self.0
24            }
25        }
26
27        impl std::ops::DerefMut for $ty {
28            fn deref_mut(&mut self) -> &mut Self::Target {
29                &mut self.0
30            }
31        }
32    };
33}
34
35/// Little Endian (LE) wrapper type
36/// This type is used to indicate that the value is in little endian format
37/// It's primary use is in deriving from `BinaryIo` trait
38///
39/// # Example
40/// ```rust ignore
41/// use binary_util::types::LE;
42/// use binary_util::BinaryIo;
43///
44/// #[derive(BinaryIo)]
45/// struct MyStruct {
46///    test: LE<u32>,
47/// }
48/// ```
49#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
50pub struct LE<T>(pub T);
51
52impl<T> LE<T> {
53    pub fn new(val: T) -> Self {
54        Self(val)
55    }
56}
57impl_type!(LE<u16>, u16);
58impl_type!(LE<u24>, u24);
59impl_type!(LE<u32>, u32);
60impl_type!(LE<u64>, u64);
61impl_type!(LE<u128>, u128);
62impl_type!(LE<i16>, i16);
63impl_type!(LE<i24>, i24);
64impl_type!(LE<i32>, i32);
65impl_type!(LE<i64>, i64);
66impl_type!(LE<i128>, i128);
67impl_type!(LE<f32>, f32);
68impl_type!(LE<f64>, f64);
69
70/// Big Endian (BE) wrapper type
71/// This type is used to indicate that the value is in big endian format
72/// It's primary use is in deriving from `BinaryIo` trait
73///
74/// # Example
75/// ```rust ignore
76/// use binary_util::types::BE;
77/// use binary_util::BinaryIo;
78///
79/// #[derive(BinaryIo)]
80/// struct MyStruct {
81///   test: BE<u32>,
82/// }
83/// ```
84#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
85pub struct BE<T>(pub T);
86
87impl<T> BE<T> {
88    pub fn new(val: T) -> Self {
89        Self(val)
90    }
91}
92
93impl_type!(BE<u16>, u16);
94impl_type!(BE<u24>, u24);
95impl_type!(BE<u32>, u32);
96impl_type!(BE<u64>, u64);
97impl_type!(BE<u128>, u128);
98impl_type!(BE<i16>, i16);
99impl_type!(BE<i24>, i24);
100impl_type!(BE<i32>, i32);
101impl_type!(BE<i64>, i64);
102impl_type!(BE<i128>, i128);
103impl_type!(BE<f32>, f32);
104impl_type!(BE<f64>, f64);
105
106/// Unsigned 24 bit integer explicit type.
107/// You should really only use this when you need to derive the `BinaryIo` trait
108/// as it is a helper type.
109///
110/// # Example
111/// ```rust ignore
112/// use binary_util::types::u24;
113/// use binary_util::BinaryIo;
114///
115/// #[derive(BinaryIo)]
116/// struct MyStruct {
117///    test: u24,
118/// }
119/// ```
120#[allow(non_camel_case_types)]
121#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
122pub struct u24(pub u32);
123
124impl u24 {
125    pub fn new(val: u32) -> Self {
126        if val <= 0xFFFFFF {
127            Self(val)
128        } else {
129            panic!("u24: value out of range")
130        }
131    }
132}
133
134impl fmt::Display for u24 {
135    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136        write!(f, "{}", self.0)
137    }
138}
139
140impl_type!(u24, u32);
141
142/// Signed 24 bit integer explicit type.
143/// You should really only use this when you need to derive the `BinaryIo` trait
144/// as it is a helper type.
145///
146/// # Example
147/// ```rust ignore
148/// use binary_util::types::i24;
149/// use binary_util::BinaryIo;
150///
151/// #[derive(BinaryIo)]
152/// struct MyStruct {
153///   test: i24,
154/// }
155/// ```
156#[allow(non_camel_case_types)]
157#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
158pub struct i24(pub i32);
159
160impl i24 {
161    pub fn new(val: i32) -> Self {
162        if val >= -0x800000 && val <= 0x7FFFFF {
163            Self(val)
164        } else {
165            panic!("i24: value out of range")
166        }
167    }
168}
169
170impl fmt::Display for i24 {
171    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172        write!(f, "{}", self.0)
173    }
174}
175
176impl_type!(i24, i32);
177
178/// A variable length integer type that can be up to 32 bits.
179/// This is a helper type for deriving the `BinaryIo` trait.
180///
181/// You should not use this type directly, if you are reading or writing
182/// a variable length integer, use the `ByteWriter` or `ByteReader` and use
183/// the corresponding `read_var_u32` or `write_var_u32` methods.
184#[allow(non_camel_case_types)]
185#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
186pub struct varu32(pub u32);
187
188impl varu32 {
189    pub fn new(val: u32) -> Self {
190        Self(val)
191    }
192}
193impl_type!(varu32, u32);
194
195/// A variable length integer type that can be up to 32 bits.
196/// This is a helper type for deriving the `BinaryIo` trait.
197///
198/// You should not use this type directly, if you are reading or writing
199/// a variable length integer, use the `ByteWriter` or `ByteReader` and use
200/// the corresponding `read_var_i32` or `write_var_i32` methods.
201#[allow(non_camel_case_types)]
202#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
203pub struct vari32(pub i32);
204
205impl vari32 {
206    pub fn new(val: i32) -> Self {
207        Self(val)
208    }
209}
210impl_type!(vari32, i32);
211
212/// A variable length integer type that can be up to 64 bits.
213/// This is a helper type for deriving the `BinaryIo` trait.
214///
215/// > You should not use this type directly, if you are reading or writing
216/// > a variable length integer, use the `ByteWriter` or `ByteReader` and use
217/// > the corresponding `read_var_u64` or `write_var_u64` methods.
218#[allow(non_camel_case_types)]
219#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
220pub struct varu64(pub u64);
221
222impl varu64 {
223    pub fn new(val: u64) -> Self {
224        Self(val)
225    }
226}
227
228impl_type!(varu64, u64);
229
230/// A variable length integer type that can be up to 64 bits.
231/// This is a helper type for deriving the `BinaryIo` trait.
232///
233/// > You should not use this type directly, if you are reading or writing
234/// > a variable length integer, use the `ByteWriter` or `ByteReader` and use
235/// > the corresponding `read_var_i64` or `write_var_i64` methods.
236#[allow(non_camel_case_types)]
237#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
238pub struct vari64(pub i64);
239
240impl vari64 {
241    pub fn new(val: i64) -> Self {
242        Self(val)
243    }
244}
245
246impl_type!(vari64, i64);