1use core::{
5 cmp::Ordering,
6 fmt,
7 hash::{Hash, Hasher},
8};
9pub use zerocopy::*;
10
11#[cfg(feature = "generator")]
12use bolero_generator::prelude::*;
13
14#[macro_export]
17macro_rules! zerocopy_value_codec {
18 ($name:ident) => {
19 impl<'a> $crate::DecoderValue<'a> for $name
20 where
21 $name: $crate::zerocopy::FromBytes,
22 {
23 #[inline]
24 fn decode(buffer: $crate::DecoderBuffer<'a>) -> $crate::DecoderBufferResult<'a, Self> {
25 let (value, buffer) = <&'a $name as $crate::DecoderValue>::decode(buffer)?;
26 Ok((*value, buffer))
27 }
28 }
29
30 impl<'a> $crate::DecoderValue<'a> for &'a $name
31 where
32 $name: $crate::zerocopy::FromBytes,
33 {
34 #[inline]
35 fn decode(buffer: $crate::DecoderBuffer<'a>) -> $crate::DecoderBufferResult<'a, Self> {
36 let (value, buffer) = buffer.decode_slice(core::mem::size_of::<$name>())?;
37 let value = value.into_less_safe_slice();
38 let value = unsafe {
39 &*(value as *const _ as *const $name)
41 };
42 Ok((value, buffer.into()))
43 }
44 }
45
46 impl<'a> $crate::DecoderValueMut<'a> for $name
47 where
48 $name: $crate::zerocopy::FromBytes,
49 {
50 #[inline]
51 fn decode_mut(
52 buffer: $crate::DecoderBufferMut<'a>,
53 ) -> $crate::DecoderBufferMutResult<'a, Self> {
54 let (value, buffer) = <&'a $name as $crate::DecoderValueMut>::decode_mut(buffer)?;
55 Ok((*value, buffer))
56 }
57 }
58
59 impl<'a> $crate::DecoderValueMut<'a> for &'a $name
60 where
61 $name: $crate::zerocopy::FromBytes,
62 {
63 #[inline]
64 fn decode_mut(
65 buffer: $crate::DecoderBufferMut<'a>,
66 ) -> $crate::DecoderBufferMutResult<'a, Self> {
67 let (value, buffer) =
68 <&'a mut $name as $crate::DecoderValueMut>::decode_mut(buffer)?;
69 Ok((value, buffer))
70 }
71 }
72
73 impl<'a> $crate::DecoderValueMut<'a> for &'a mut $name
74 where
75 $name: $crate::zerocopy::FromBytes,
76 {
77 #[inline]
78 fn decode_mut(
79 buffer: $crate::DecoderBufferMut<'a>,
80 ) -> $crate::DecoderBufferMutResult<'a, Self> {
81 let (value, buffer) = buffer.decode_slice(core::mem::size_of::<$name>())?;
82 let value = value.into_less_safe_slice();
83 let value = unsafe {
84 &mut *(value as *mut _ as *mut $name)
86 };
87
88 Ok((value, buffer.into()))
89 }
90 }
91
92 impl $crate::EncoderValue for $name
93 where
94 $name: $crate::zerocopy::IntoBytes,
95 {
96 #[inline]
97 fn encoding_size(&self) -> usize {
98 core::mem::size_of::<$name>()
99 }
100
101 #[inline]
102 fn encoding_size_for_encoder<E: $crate::Encoder>(&self, _encoder: &E) -> usize {
103 core::mem::size_of::<$name>()
104 }
105
106 #[inline]
107 fn encode<E: $crate::Encoder>(&self, encoder: &mut E) {
108 let bytes = unsafe {
109 core::slice::from_raw_parts(
111 self as *const $name as *const u8,
112 core::mem::size_of::<$name>(),
113 )
114 };
115 encoder.write_slice(bytes);
116 }
117 }
118
119 impl<'a> $crate::EncoderValue for &'a $name
120 where
121 $name: $crate::zerocopy::IntoBytes,
122 {
123 #[inline]
124 fn encoding_size(&self) -> usize {
125 core::mem::size_of::<$name>()
126 }
127
128 #[inline]
129 fn encoding_size_for_encoder<E: $crate::Encoder>(&self, _encoder: &E) -> usize {
130 ::core::mem::size_of::<$name>()
131 }
132
133 #[inline]
134 fn encode<E: $crate::Encoder>(&self, encoder: &mut E) {
135 let bytes = unsafe {
136 core::slice::from_raw_parts(
138 *self as *const $name as *const u8,
139 core::mem::size_of::<$name>(),
140 )
141 };
142 encoder.write_slice(bytes);
143 }
144 }
145
146 impl<'a> $crate::EncoderValue for &'a mut $name
147 where
148 $name: $crate::zerocopy::IntoBytes,
149 {
150 #[inline]
151 fn encoding_size(&self) -> usize {
152 core::mem::size_of::<$name>()
153 }
154
155 #[inline]
156 fn encoding_size_for_encoder<E: $crate::Encoder>(&self, _encoder: &E) -> usize {
157 ::core::mem::size_of::<$name>()
158 }
159
160 #[inline]
161 fn encode<E: $crate::Encoder>(&self, encoder: &mut E) {
162 let bytes = unsafe {
163 core::slice::from_raw_parts(
165 *self as *const $name as *const u8,
166 core::mem::size_of::<$name>(),
167 )
168 };
169 encoder.write_slice(bytes);
170 }
171 }
172 };
173}
174
175macro_rules! zerocopy_network_integer {
179 ($native:ident, $name:ident) => {
180 #[derive(
181 Clone,
182 Copy,
183 Default,
184 Eq,
185 Immutable,
186 $crate::zerocopy::FromBytes,
187 $crate::zerocopy::IntoBytes,
188 $crate::zerocopy::Unaligned,
189 )]
190 #[repr(C)]
191 pub struct $name(::zerocopy::byteorder::$name<NetworkEndian>);
192
193 impl $name {
194 pub const ZERO: Self = Self(::zerocopy::byteorder::$name::ZERO);
195
196 #[inline(always)]
197 pub fn new(value: $native) -> Self {
198 value.into()
199 }
200
201 #[inline(always)]
202 pub fn get(&self) -> $native {
203 self.get_be().to_be()
204 }
205
206 #[inline(always)]
207 pub fn get_be(&self) -> $native {
208 unsafe {
209 $native::from_ne_bytes(
210 *(self.0.as_bytes().as_ptr()
211 as *const [u8; ::core::mem::size_of::<$native>()]),
212 )
213 }
214 }
215
216 #[inline(always)]
217 pub fn set(&mut self, value: $native) {
218 self.0.as_mut_bytes().copy_from_slice(&value.to_be_bytes());
219 }
220
221 #[inline(always)]
222 pub fn set_be(&mut self, value: $native) {
223 self.0.as_mut_bytes().copy_from_slice(&value.to_ne_bytes());
224 }
225 }
226
227 impl PartialEq for $name {
228 #[inline]
229 fn eq(&self, other: &Self) -> bool {
230 self.cmp(other) == Ordering::Equal
231 }
232 }
233
234 impl PartialEq<$native> for $name {
235 #[inline]
236 fn eq(&self, other: &$native) -> bool {
237 self.partial_cmp(other) == Some(Ordering::Equal)
238 }
239 }
240
241 impl PartialOrd for $name {
242 #[inline]
243 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
244 Some(self.cmp(other))
245 }
246 }
247
248 impl PartialOrd<$native> for $name {
249 #[inline]
250 fn partial_cmp(&self, other: &$native) -> Option<Ordering> {
251 Some(self.get().cmp(other))
252 }
253 }
254
255 impl Ord for $name {
256 #[inline]
257 fn cmp(&self, other: &Self) -> Ordering {
258 self.get_be().cmp(&other.get_be())
259 }
260 }
261
262 impl Hash for $name {
263 fn hash<H: Hasher>(&self, state: &mut H) {
264 self.get().hash(state);
265 }
266 }
267
268 impl fmt::Debug for $name {
269 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
270 write!(formatter, "{}", self.get())
271 }
272 }
273
274 impl fmt::Display for $name {
275 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
276 write!(formatter, "{}", self.get())
277 }
278 }
279
280 impl From<$native> for $name {
281 #[inline]
282 fn from(value: $native) -> Self {
283 Self(::zerocopy::byteorder::$name::new(value))
284 }
285 }
286
287 impl From<$name> for $native {
288 #[inline]
289 fn from(v: $name) -> $native {
290 v.get()
291 }
292 }
293
294 #[cfg(feature = "generator")]
295 impl TypeGenerator for $name {
296 fn generate<D: bolero_generator::Driver>(driver: &mut D) -> Option<Self> {
297 Some(Self::new(driver.produce()?))
298 }
299 }
300
301 #[cfg(kani)]
302 impl kani::Arbitrary for $name {
303 fn any() -> Self {
304 Self::new(kani::any())
305 }
306 }
307
308 zerocopy_value_codec!($name);
309 };
310}
311
312zerocopy_network_integer!(i16, I16);
313zerocopy_network_integer!(u16, U16);
314zerocopy_network_integer!(i32, I32);
315zerocopy_network_integer!(u32, U32);
316zerocopy_network_integer!(i64, I64);
317zerocopy_network_integer!(u64, U64);
318zerocopy_network_integer!(i128, I128);
319zerocopy_network_integer!(u128, U128);
320
321#[test]
322fn zerocopy_struct_test() {
323 use crate::DecoderBuffer;
324
325 #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, FromBytes, IntoBytes, Unaligned)]
326 #[repr(C)]
327 struct UdpHeader {
328 source_port: U16,
329 destination_port: U16,
330 payload_len: U16,
331 checksum: U16,
332 }
333
334 zerocopy_value_codec!(UdpHeader);
335
336 let buffer = vec![0, 1, 0, 2, 0, 3, 0, 4];
337 let decoder = DecoderBuffer::new(&buffer);
338 let (mut header, _) = decoder.decode().unwrap();
339
340 ensure_codec_round_trip_value!(UdpHeader, header).unwrap();
341 ensure_codec_round_trip_value!(&UdpHeader, &header).unwrap();
342 ensure_codec_round_trip_value_mut!(&mut UdpHeader, &mut header).unwrap();
343
344 assert_eq!(header.source_port, 1u16);
345 assert_eq!(header.destination_port, 2u16);
346 assert_eq!(header.payload_len, 3u16);
347 assert_eq!(header.checksum, 4u16);
348}