1#![allow(unused_parens)]
2
3use crate::{check_len, Error, Result, TryRead, TryWrite};
4use core::convert::TryInto;
5use core::mem;
6
7#[derive(Debug, PartialEq, Eq, Copy, Clone)]
25pub enum Endian {
26 Little,
28 Big,
30}
31
32impl Default for Endian {
33 #[inline]
34 fn default() -> Self {
35 NATIVE
36 }
37}
38
39pub const LE: Endian = Endian::Little;
41pub const BE: Endian = Endian::Big;
43
44pub const NETWORK: Endian = Endian::Little;
46
47#[cfg(target_endian = "little")]
49pub const NATIVE: Endian = LE;
50#[cfg(target_endian = "big")]
52pub const NATIVE: Endian = BE;
53
54macro_rules! num_impl {
55 ($ty: ty, $size: tt) => {
56 impl<'a> TryRead<'a, Endian> for $ty {
57 #[inline]
58 fn try_read(bytes: &'a [u8], endian: Endian) -> Result<(Self, usize)> {
59 check_len(bytes, $size)?;
60
61 let val = match endian {
62 Endian::Big => {
63 <$ty>::from_be_bytes(bytes[..$size].try_into().map_err(|_e| {
64 Error::BadInput {
65 err: "TryIntoSliceError",
66 }
67 })?)
68 }
69 Endian::Little => {
70 <$ty>::from_le_bytes(bytes[..$size].try_into().map_err(|_e| {
71 Error::BadInput {
72 err: "TryIntoSliceError",
73 }
74 })?)
75 }
76 };
77
78 Ok((val, $size))
79 }
80 }
81
82 impl TryWrite<Endian> for $ty {
83 #[inline]
84 fn try_write(self, bytes: &mut [u8], endian: Endian) -> Result<usize> {
85 check_len(bytes, $size)?;
86
87 let _val = match endian {
88 Endian::Big => bytes[..$size].copy_from_slice(&self.to_be_bytes()),
89 Endian::Little => bytes[..$size].copy_from_slice(&self.to_le_bytes()),
90 };
91
92 Ok($size)
93 }
94 }
95 };
96}
97
98num_impl!(u8, 1);
99num_impl!(u16, 2);
100num_impl!(u32, 4);
101num_impl!(u64, 8);
102num_impl!(i8, 1);
103num_impl!(i16, 2);
104num_impl!(i32, 4);
105num_impl!(i64, 8);
106num_impl!(usize, (mem::size_of::<usize>()));
107num_impl!(isize, (mem::size_of::<isize>()));
108
109macro_rules! float_impl {
110 ($ty: ty, $base: ty) => {
111 impl<'a> TryRead<'a, Endian> for $ty {
112 #[inline]
113 fn try_read(bytes: &'a [u8], endian: Endian) -> Result<(Self, usize)> {
114 <$base as TryRead<'a, Endian>>::try_read(bytes, endian)
115 .map(|(val, size)| (<$ty>::from_bits(val), size))
116 }
117 }
118
119 impl<'a> TryWrite<Endian> for $ty {
120 #[inline]
121 fn try_write(self, bytes: &mut [u8], endian: Endian) -> Result<usize> {
122 <$base as TryWrite<Endian>>::try_write(self.to_bits(), bytes, endian)
123 }
124 }
125 };
126}
127
128float_impl!(f32, u32);
129float_impl!(f64, u64);