1pub(crate) trait Imm {
10    fn bytes(&self) -> &[u8];
12}
13
14macro_rules! impl_imm {
15    (#[$doc:meta] $name:ident, $size:expr, from: { $( $from:ty ),* $(,)? }) => {
16        #[$doc]
17        pub struct $name([u8; $size]);
18
19        impl Imm for $name {
20            fn bytes(&self) -> &[u8] {
22                &self.0
23            }
24        }
25
26        $(
27        impl From<$from> for $name {
28            fn from(imm: $from) -> Self {
29                let mut buf = [0u8; $size];
30                let imm = imm.to_ne_bytes();
31                buf[0..imm.len()].copy_from_slice(&imm);
32                $name(buf)
33            }
34        }
35        )*
36    }
37}
38
39impl_imm!(
40    Imm8, 1, from: { u8, i8 }
42);
43impl_imm!(
44    Imm16, 2, from: { u16, i16, u8, i8 }
46);
47impl_imm!(
48    Imm32, 4, from: { u32, i32, u16, i16, u8, i8 }
50);
51impl_imm!(
52    Imm64, 8, from: { u64, i64, u32, i32, u16, i16, u8, i8, usize, isize }
54);
55
56#[cfg(test)]
57mod test {
58    use super::*;
59    use std::mem::size_of;
60
61    #[test]
62    fn test_usize_isize() {
63        assert_eq!(size_of::<usize>(), size_of::<Imm64>());
65        assert_eq!(size_of::<isize>(), size_of::<Imm64>());
66    }
67}