userspace/macros/structs/
default.rs1#[macro_export]
2macro_rules! r#struct {
3 ($vis:vis $struct_identifier:ident {$($field_visibility:vis $field_identifier:ident: $field_type:ty),*$(,)?}) => {
4
5 #[derive(Debug, Clone, Copy)]
7 $vis struct $struct_identifier {
8 $($field_visibility $field_identifier: $field_type),*
9 }
10
11 impl $crate::traits::Bytes<crate::Origin,crate::Origin> for $struct_identifier {
12 const BYTES_SIZE : usize = $(<$field_type as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE +)* 0;
13
14 fn to_bytes(&self, endianness: bool) -> [u8; Self::BYTES_SIZE] {
15 let mut b = [0u8; Self::BYTES_SIZE];
16 let mut o = 0;
17 $(
18 b[o..(o+<$field_type as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE)].copy_from_slice(
19 &if endianness {
20 <$field_type as $crate::traits::Bytes<crate::Origin,crate::Origin>>::to_le_bytes(&self.$field_identifier)
21 } else {
22 <$field_type as $crate::traits::Bytes<crate::Origin,crate::Origin>>::to_be_bytes(&self.$field_identifier)
23 }
24 );
25 o = o + <$field_type as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE;
26 )*
27 b
28 }
29
30 fn from_bytes(bytes : [u8; Self::BYTES_SIZE], endianness: bool) -> Self {
31 let mut o = 0;
32 $(
33 let mut field_bytes = [0u8; <$field_type as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE];
34 field_bytes.copy_from_slice(&bytes[o..(o+<$field_type as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE)]);
35 let $field_identifier = if endianness {
36 <$field_type as $crate::traits::Bytes<crate::Origin,crate::Origin>>::from_le_bytes(field_bytes)
37 } else {
38 <$field_type as $crate::traits::Bytes<crate::Origin,crate::Origin>>::from_be_bytes(field_bytes)
39 };
40 o = o + <$field_type as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE;
41 )*
42 Self {
43 $($field_identifier,)*
44 }
45 }
46 }
47
48 type OptionDiscriminant = u8;
49 impl $crate::traits::Bytes<crate::Origin,crate::Origin> for Option<$struct_identifier> {
50 const BYTES_SIZE: usize = <OptionDiscriminant as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE + <$struct_identifier as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE;
51 fn from_bytes(bytes: [u8; Self::BYTES_SIZE], endianness: bool) -> Self {
52 let mut option_bytes = [0u8; <OptionDiscriminant as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE];
53 let mut o = 0;
54 let mut l = <OptionDiscriminant as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE;
55 option_bytes.copy_from_slice(&bytes[o..l]);
56 let option = if endianness {
57 <OptionDiscriminant as $crate::traits::Bytes<crate::Origin,crate::Origin>>::from_le_bytes(option_bytes)
58 } else {
59 <OptionDiscriminant as $crate::traits::Bytes<crate::Origin,crate::Origin>>::from_be_bytes(option_bytes)
60 };
61 if option == 0 {
62 None
63 } else {
64 o = l;
65 l = l + <$struct_identifier as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE;
66 let mut value_bytes = [0u8; <$struct_identifier as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE];
67 value_bytes.copy_from_slice(&bytes[o..l]);
68 if endianness {
69 Some(<$struct_identifier as $crate::traits::Bytes<crate::Origin,crate::Origin>>::from_le_bytes(value_bytes))
70 } else {
71 Some(<$struct_identifier as $crate::traits::Bytes<crate::Origin,crate::Origin>>::from_be_bytes(value_bytes))
72 }
73 }
74 }
75
76 fn to_bytes(&self, endianness: bool) -> [u8; Self::BYTES_SIZE] {
77 let mut bytes = [0u8; Self::BYTES_SIZE];
78 if let Some(v) = self {
79 let mut o = 0;
80 let mut l = <OptionDiscriminant as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE;
81 bytes[o..l].copy_from_slice(&(1 as OptionDiscriminant).to_le_bytes());
82 o = l;
83 l = l + <$struct_identifier as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE;
84 if endianness {
85 bytes[o..l].copy_from_slice(&<$struct_identifier as $crate::traits::Bytes<crate::Origin,crate::Origin>>::to_le_bytes(v));
86 } else {
87 bytes[o..l].copy_from_slice(&<$struct_identifier as $crate::traits::Bytes<crate::Origin,crate::Origin>>::to_be_bytes(v));
88 }
89 bytes
90 } else {
91 bytes
92 }
93 }
94 }
95 }
96}
97pub use r#struct;