gdbstub/internal/
le_bytes.rs1pub trait LeBytes: Sized {
4 #[allow(clippy::wrong_self_convention)]
7 fn to_le_bytes(self, buf: &mut [u8]) -> Option<usize>;
8
9 fn from_le_bytes(buf: &[u8]) -> Option<Self>;
12}
13
14macro_rules! impl_to_le_bytes {
15 ($($num:ty)*) => {
16 $(
17 impl LeBytes for $num {
18 fn to_le_bytes(self, buf: &mut [u8]) -> Option<usize> {
19 let len = core::mem::size_of::<$num>();
20 if buf.len() < len {
21 return None
22 }
23 buf[..len].copy_from_slice(&<$num>::to_le_bytes(self));
24 Some(len)
25 }
26
27 fn from_le_bytes(buf: &[u8]) -> Option<Self> {
28 let len = core::mem::size_of::<$num>();
29
30 let buf = if buf.len() > len {
31 let (extra, buf) = buf.split_at(buf.len() - len);
32 if extra.iter().any(|&b| b != 0) {
33 return None
34 }
35 buf
36 } else {
37 buf
38 };
39
40 let mut res: Self = 0;
41 for b in buf.iter().copied().rev() {
42 let b: Self = b as Self;
43 res <<= 4;
45 res <<= 4;
46 res |= b;
47 }
48
49 Some(res)
50 }
51 }
52 )*
53 };
54}
55
56impl_to_le_bytes!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn basic() {
64 assert_eq!(
65 0x12345678,
66 LeBytes::from_le_bytes(&[0x78, 0x56, 0x34, 0x12]).unwrap()
67 )
68 }
69
70 #[test]
71 fn small() {
72 assert_eq!(
73 0x123456,
74 LeBytes::from_le_bytes(&[0x56, 0x34, 0x12]).unwrap()
75 )
76 }
77
78 #[test]
79 fn too_big() {
80 assert_eq!(
81 0x1234_u16,
82 LeBytes::from_le_bytes(&[0xde, 0xad, 0xbe, 0xef]).unwrap_or(0x1234)
83 )
84 }
85}