userspace/macros/traits/
bytes.rs

1#[macro_export]
2macro_rules! trait_implement_bytes {
3    ($($t:ty),*) => {
4        $(
5            impl $crate::traits::Bytes<crate::Origin,crate::Origin> for $t {
6                const BYTES_SIZE: usize = core::mem::size_of::<Self>();
7
8                fn to_bytes(&self, endianness: bool) -> [u8; <Self as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE] {
9                    if endianness {
10                        <Self as $crate::traits::Bytes<crate::Origin,crate::Origin>>::to_le_bytes(self)
11                    } else {
12                        <Self as $crate::traits::Bytes<crate::Origin,crate::Origin>>::to_be_bytes(self)
13                    }
14                }
15
16                fn from_bytes(bytes: [u8; <Self as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE], endianness: bool) -> Self {
17                    if endianness {
18                        <Self as $crate::traits::Bytes<crate::Origin,crate::Origin>>::from_le_bytes(bytes)
19                    } else {
20                        <Self as $crate::traits::Bytes<crate::Origin,crate::Origin>>::from_be_bytes(bytes)
21                    }
22                }
23            }
24
25            impl $crate::traits::Bytes<crate::Origin,crate::Origin> for Option<$t> {
26                const BYTES_SIZE: usize = core::mem::size_of::<u8>() + <$t as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE;
27                fn from_bytes(bytes: [u8; <Self as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE], endianness: bool) -> Self {
28                    let mut option_bytes = [0u8; <u8 as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE];
29                    let mut o = 0;
30                    let mut l = <u8 as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE;
31                    option_bytes.copy_from_slice(&bytes[o..l]);
32                    let option = if endianness {
33                        <u8 as $crate::traits::Bytes<crate::Origin,crate::Origin>>::from_le_bytes(option_bytes)
34                    } else {
35                        <u8 as $crate::traits::Bytes<crate::Origin,crate::Origin>>::from_be_bytes(option_bytes)
36                    };
37                    if option == 0 {
38                        None
39                    } else {
40                        o = l;
41                        l = l + <$t as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE;
42                        let mut value_bytes = [0u8; <$t as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE];
43                        value_bytes.copy_from_slice(&bytes[o..l]);
44                        if endianness {
45                            Some(<$t as $crate::traits::Bytes<crate::Origin,crate::Origin>>::from_le_bytes(value_bytes))
46                        } else {
47                            Some(<$t as $crate::traits::Bytes<crate::Origin,crate::Origin>>::from_be_bytes(value_bytes))
48                        }
49                    }
50                }
51
52                fn to_bytes(&self, endianness: bool) -> [u8; <Self as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE] {
53                    let mut bytes = [0u8; <Self as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE];
54                    if let Some(v) = self {
55                        let mut o = 0;
56                        let mut l = <u8 as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE;
57                        bytes[o..l].copy_from_slice(&1u8.to_le_bytes());
58                        o = l;
59                        l = l + <$t as $crate::traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE;
60                        if endianness {
61                            bytes[o..l].copy_from_slice(&<$t as $crate::traits::Bytes<crate::Origin,crate::Origin>>::to_le_bytes(v));
62                        } else {
63                            bytes[o..l].copy_from_slice(&<$t as $crate::traits::Bytes<crate::Origin,crate::Origin>>::to_be_bytes(v));
64                        }
65                        bytes
66                    } else {
67                        bytes
68                    }
69                }
70            }
71
72            impl $crate::traits::Bytes<crate::Origin, crate::Origin> for *const $t {
73                const BYTES_SIZE: usize = core::mem::size_of::<Self>();
74                fn to_bytes(&self, endianness: bool) -> [u8; <Self as $crate::traits::Bytes<crate::Origin, crate::Origin>>::BYTES_SIZE] {
75                    if endianness {
76                        usize::to_le_bytes(*self as usize)
77                    } else {
78                        usize::to_be_bytes(*self as usize)
79                    }
80                }
81
82                fn from_bytes(bytes: [u8; <Self as $crate::traits::Bytes<crate::Origin, crate::Origin>>::BYTES_SIZE], endianness: bool) -> Self {
83                    if endianness {
84                        usize::from_le_bytes(bytes) as Self
85                    } else {
86                        usize::from_be_bytes(bytes) as Self
87                    }
88                }
89            }
90        )*
91    };
92}
93
94// #[macro_export]
95// macro_rules! trait_place_bytes {
96//     () => {
97//         pub trait Bytes {
98//             const BYTES_SIZE: usize;
99
100//             fn to_bytes(&self, endianness: bool) -> [u8; Self::BYTES_SIZE];
101//             fn to_le_bytes(&self) -> [u8; Self::BYTES_SIZE] {
102//                 self.to_bytes(true)
103//             }
104//             fn to_be_bytes(&self) -> [u8; Self::BYTES_SIZE] {
105//                 self.to_bytes(false)
106//             }
107//             fn from_bytes(bytes: [u8; Self::BYTES_SIZE], endianness: bool) -> Self;
108//             fn from_le_bytes(bytes: [u8; Self::BYTES_SIZE]) -> Self
109//             where
110//                 Self: Sized,
111//             {
112//                 Self::from_bytes(bytes, true)
113//             }
114//             fn from_be_bytes(bytes: [u8; Self::BYTES_SIZE]) -> Self
115//             where
116//                 Self: Sized,
117//             {
118//                 Self::from_bytes(bytes, false)
119//             }
120//         }
121//     };
122//     (1) => {
123//         pub trait Bytes {
124//             const BYTES_SIZE: usize;
125
126//             fn to_bytes(&self, endianness: bool) -> [u8; Self::BYTES_SIZE]
127//             where
128//                 [u8; Self::BYTES_SIZE]:;
129//             fn to_le_bytes(&self) -> [u8; Self::BYTES_SIZE]
130//             where
131//                 [u8; Self::BYTES_SIZE]:,
132//             {
133//                 self.to_bytes(true)
134//             }
135//             fn to_be_bytes(&self) -> [u8; Self::BYTES_SIZE]
136//             where
137//                 [u8; Self::BYTES_SIZE]:,
138//             {
139//                 self.to_bytes(false)
140//             }
141//             fn from_bytes(bytes: [u8; Self::BYTES_SIZE], endianness: bool) -> Self
142//             where
143//                 [u8; Self::BYTES_SIZE]:;
144//             fn from_le_bytes(bytes: [u8; Self::BYTES_SIZE]) -> Self
145//             where
146//                 Self: Sized,
147//                 [u8; Self::BYTES_SIZE]:,
148//             {
149//                 Self::from_bytes(bytes, true)
150//             }
151//             fn from_be_bytes(bytes: [u8; Self::BYTES_SIZE]) -> Self
152//             where
153//                 Self: Sized,
154//                 [u8; Self::BYTES_SIZE]:,
155//             {
156//                 Self::from_bytes(bytes, false)
157//             }
158//         }
159//     };
160// }
161
162// impl_pointer!(Pci8, Pcu);
163#[macro_export]
164macro_rules! traits_implement_bytes_tuple {
165    ($($($ordinal_type:tt)::*),*) => {
166        impl $crate::traits::Bytes<crate::Origin, crate::Origin> for ($($($ordinal_type)::*),*) {
167            const BYTES_SIZE: usize = $(<$($ordinal_type)::* as $crate::traits::Bytes<crate::Origin, crate::Origin>>::BYTES_SIZE + )* 0;
168            fn to_bytes(
169                &self,
170                endianness: bool,
171            ) -> [u8; <Self as $crate::traits::Bytes<crate::Origin, crate::Origin>>::BYTES_SIZE] {
172                let mut pair_bytes =
173                    [0u8; <Self as $crate::traits::Bytes<crate::Origin, crate::Origin>>::BYTES_SIZE];
174
175                if endianness {
176                    let mut o = 0;
177                    let mut l = <Pcu as $crate::traits::Bytes<crate::Origin, crate::Origin>>::BYTES_SIZE;
178                    pair_bytes[o..l].copy_from_slice(&self.0.to_le_bytes());
179                    o = l;
180                    l = l + <Pci8 as $crate::traits::Bytes<crate::Origin, crate::Origin>>::BYTES_SIZE;
181                    pair_bytes[o..l].copy_from_slice(&self.1.to_le_bytes());
182                } else {
183                    let mut o = 0;
184                    let mut l = <Pcu as $crate::traits::Bytes<crate::Origin, crate::Origin>>::BYTES_SIZE;
185                    pair_bytes[o..l].copy_from_slice(&self.0.to_be_bytes());
186                    o = l;
187                    l = l + <Pci8 as $crate::traits::Bytes<crate::Origin, crate::Origin>>::BYTES_SIZE;
188                    pair_bytes[o..l].copy_from_slice(&self.1.to_be_bytes());
189                }
190
191                pair_bytes
192            }
193
194            fn from_bytes(bytes: [u8; Self::BYTES_SIZE], endianness: bool) -> Self {
195                let mut left_bytes =
196                    [0u8; <Pcu as $crate::traits::Bytes<crate::Origin, crate::Origin>>::BYTES_SIZE];
197                let mut right_bytes =
198                    [0u8; <Pci8 as $crate::traits::Bytes<crate::Origin, crate::Origin>>::BYTES_SIZE];
199
200                let mut o = 0;
201                let mut l = <Pcu as $crate::traits::Bytes<crate::Origin, crate::Origin>>::BYTES_SIZE;
202
203                left_bytes.copy_from_slice(&bytes[o..l]);
204
205                o = l;
206                l = l + <Pci8 as $crate::traits::Bytes<crate::Origin, crate::Origin>>::BYTES_SIZE;
207
208                right_bytes.copy_from_slice(&bytes[o..l]);
209
210                if endianness {
211                    let left = <Pcu as $crate::traits::Bytes<crate::Origin, crate::Origin>>::from_le_bytes(
212                        left_bytes,
213                    );
214                    let right =
215                        <Pci8 as $crate::traits::Bytes<crate::Origin, crate::Origin>>::from_le_bytes(
216                            right_bytes,
217                        );
218                    (left, right)
219                } else {
220                    let left = <Pcu as $crate::traits::Bytes<crate::Origin, crate::Origin>>::from_be_bytes(
221                        left_bytes,
222                    );
223                    let right =
224                        <Pci8 as $crate::traits::Bytes<crate::Origin, crate::Origin>>::from_be_bytes(
225                            right_bytes,
226                        );
227                    (left, right)
228                }
229            }
230        }
231    };
232}
233pub use trait_implement_bytes;
234pub use traits_implement_bytes_tuple;