num_bytes/
lib.rs

1//! A crate to allow converting generic from/into bytes.
2//!
3//! Defines `FromBytes` and `IntoBytes` traits.
4//! 
5//! Implements them on all numerical primitives.
6//!
7//! Usage is a little tricky:
8//! ```
9//! let a = [8,0];
10//! let b: i16 = from_generic(a);
11//! assert_eq!(b,8);
12//! fn from_generic<T: num_bytes::FromBytes<N>, const N: usize>(x: [u8;N]) -> T {
13//!     T::from_le_bytes(x)
14//! }
15//! ```
16//! ```
17//! let a = 8i16;
18//! let b = into_generic(a);
19//! assert_eq!(b,[8,0]);
20//! fn into_generic<T: num_bytes::IntoBytes<N>, const N: usize>(x: T) -> [u8;N] {
21//!     x.into_le_bytes()
22//! }
23//! ```
24
25/// Defines a type can be converted from a byte array.
26/// ```
27/// use num_bytes::FromBytes;
28/// let a = [8,0,0,0];
29/// let b = u32::from_le_bytes(a);
30/// assert_eq!(b,8);
31/// ```
32pub trait FromBytes<const T: usize> {
33    fn from_le_bytes(bytes: [u8; T]) -> Self;
34    fn from_be_bytes(bytes: [u8; T]) -> Self;
35}
36
37/// Defines a type can be converted into a byte array.
38/// ```
39/// use num_bytes::IntoBytes;
40/// let a = 8u32;
41/// let b = a.into_le_bytes();
42/// assert_eq!(b,[8,0,0,0]);
43/// ```
44pub trait IntoBytes<const T:usize> {
45    fn into_le_bytes(self) -> [u8;T];
46    fn into_be_bytes(self) -> [u8;T];
47}
48macro_rules! impl_from_bytes {
49    ($T: ty, $N: tt) => {
50        impl FromBytes<$N> for $T {
51            fn from_le_bytes(bytes: [u8; $N]) -> Self {
52                Self::from_le_bytes(bytes)
53            }
54            fn from_be_bytes(bytes: [u8; $N]) -> Self {
55                Self::from_be_bytes(bytes)
56            }
57        }
58    };
59}
60macro_rules! impl_into_bytes {
61    ($T: ty, $N: tt) => {
62        impl IntoBytes<$N> for $T {
63            fn into_le_bytes(self) -> [u8;$N] {
64                self.to_le_bytes()
65            }
66            fn into_be_bytes(self) -> [u8;$N] {
67                self.to_le_bytes()
68            }
69        }
70    };
71}
72
73// Try from implementations.
74impl_from_bytes!(i8, 1);
75impl_from_bytes!(i16, 2);
76impl_from_bytes!(i32, 4);
77impl_from_bytes!(i64, 8);
78impl_from_bytes!(u8, 1);
79impl_from_bytes!(u16, 2);
80impl_from_bytes!(u32, 4);
81impl_from_bytes!(u64, 8);
82
83impl_from_bytes!(f32, 4);
84impl_from_bytes!(f64, 8);
85
86#[cfg(target_pointer_width = "16")]
87impl_from_bytes!(isize, 2);
88#[cfg(target_pointer_width = "16")]
89impl_from_bytes!(usize, 2);
90
91#[cfg(target_pointer_width = "32")]
92impl_from_bytes!(isize, 4);
93#[cfg(target_pointer_width = "32")]
94impl_from_bytes!(usize, 4);
95
96#[cfg(target_pointer_width = "64")]
97impl_from_bytes!(isize, 8);
98#[cfg(target_pointer_width = "64")]
99impl_from_bytes!(usize, 8);
100
101// Into implementations.
102impl_into_bytes!(i8,1);
103impl_into_bytes!(i16,2);
104impl_into_bytes!(i32,4);
105impl_into_bytes!(i64,8);
106impl_into_bytes!(u8,1);
107impl_into_bytes!(u16,2);
108impl_into_bytes!(u32,4);
109impl_into_bytes!(u64,8);
110
111impl_into_bytes!(f32,4);
112impl_into_bytes!(f64,8);
113
114#[cfg(target_pointer_width = "16")]
115impl_into_bytes!(isize, 2);
116#[cfg(target_pointer_width = "16")]
117impl_into_bytes!(usize, 2);
118
119#[cfg(target_pointer_width = "32")]
120impl_into_bytes!(isize, 4);
121#[cfg(target_pointer_width = "32")]
122impl_into_bytes!(usize, 4);
123
124#[cfg(target_pointer_width = "64")]
125impl_into_bytes!(isize, 8);
126#[cfg(target_pointer_width = "64")]
127impl_into_bytes!(usize, 8);