1use paste::paste;
2
3use crate::order::Order;
4
5#[cfg(feature = "extra-integer-types")]
6use crate::primitives::*;
7
8pub trait ByteCast: Copy {
9 const SIZEOF: usize;
10 const SIGNED: bool;
11
12 fn from_bytes<O: Order>(buf: &[u8]) -> Self;
13 fn into_bytes<O: Order>(&self, buf: &mut [u8]);
14}
15
16macro_rules! impl_for {
17 ($t:ident, $read:ident, $write:ident, $signed:ident) => {
18 impl ByteCast for $t {
19 const SIZEOF: usize = std::mem::size_of::<$t>();
20 const SIGNED: bool = $signed;
21
22 fn from_bytes<O: Order>(buf: &[u8]) -> Self {
23 O::$read(buf)
24 }
25
26 fn into_bytes<O: Order>(&self, buf: &mut [u8]) {
27 O::$write(buf, *self)
28 }
29 }
30 };
31}
32
33macro_rules! impls_for {
34 ([$($tname:ident),*], $signed:ident) => {
35 $(
36 paste! {
37 impl_for!($tname, [<read_ $tname>], [<write_ $tname>], $signed);
38 }
39 )*
40 };
41}
42
43impl ByteCast for bool {
44 const SIZEOF: usize = 1;
45 const SIGNED: bool = false;
46
47 fn from_bytes<O: Order>(buf: &[u8]) -> Self {
48 !buf.is_empty() && buf[0] != 0
49 }
50
51 fn into_bytes<O: Order>(&self, buf: &mut [u8]) {
52 O::write_u8(buf, if *self { 1 } else { 0 })
53 }
54}
55
56#[cfg(feature = "extra-integer-types")]
57impl ByteCast for u24 {
58 const SIZEOF: usize = 3;
59 const SIGNED: bool = false;
60
61 fn from_bytes<O: Order>(buf: &[u8]) -> Self {
62 <O as Order>::read_u24(buf)
63 }
64
65 fn into_bytes<O: Order>(&self, buf: &mut [u8]) {
66 <O as Order>::write_u24(buf, *self)
67 }
68}
69
70impls_for! { [i8, i16, i32, i64, i128, isize], true }
71impls_for! { [u8, u16, u32, u64, u128, usize], false }