fugue_bytes/
traits.rs

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 }