Skip to main content

musli_zerocopy/
traits.rs

1//! Traits that apply to types which can safely interact with Müsli's zero copy
2//! system.
3//!
4//! Note that all of these traits are `unsafe`, and require care to implement.
5//! Please see their corresponding safety documentation or use the
6//! [`ZeroCopy`][derive@crate::ZeroCopy] derive.
7//!
8//! * [`ZeroCopy`] for types which can safely be coerced from a [`Ref<T>`] to
9//!   `&T` or `&mut T`.
10//! * [`UnsizedZeroCopy`] for types which can safely be coerced from an
11//!   [`Ref<T>`] where `T: ?Sized` to `&T` or `&mut T`.
12//! * [`ZeroSized`] for types which can be ignored when deriving
13//!   [`ZeroCopy`][derive@crate::ZeroCopy] using `#[zero_copy(ignore)]`.
14//!
15//! [`Ref<T>`]: crate::pointer::Ref
16
17#![allow(clippy::missing_safety_doc)]
18
19use core::array;
20use core::marker::PhantomData;
21use core::mem::{MaybeUninit, align_of, size_of, transmute};
22use core::num::Wrapping;
23use core::ptr::{self, NonNull};
24use core::slice;
25use core::str;
26
27use crate::buf::{Buf, Padder, Validator, Visit};
28use crate::endian::ByteOrder;
29use crate::error::{CoerceError, CoerceErrorKind, Error, ErrorKind};
30use crate::pointer::{Pointee, Size};
31
32mod sealed {
33    use crate::ZeroCopy;
34
35    pub trait Sealed {}
36    impl Sealed for str {}
37    impl<T> Sealed for [T] where T: ZeroCopy {}
38}
39
40/// Trait governing which `P` in [`Ref<T>`] where `P: ?Sized` the wrapper can
41/// handle.
42///
43/// We only support slice-like, unaligned unsized types, such as `str` and
44/// `[u8]`. We can't support types such as `dyn Debug` because metadata is a
45/// vtable which can't be serialized.
46///
47/// [`Ref<T>`]: crate::pointer::Ref
48///
49/// # Safety
50///
51/// This can only be implemented by types that:
52/// * Can only be implemented for base types which can inhabit any bit-pattern.
53///   All though custom validation can be performed during coercion (such as for
54///   `str`).
55/// * Must only be implemented for types which are not padded (as per
56///   [`ZeroCopy::PADDED`]).
57///
58/// # Examples
59///
60/// ```
61/// use musli_zerocopy::OwnedBuf;
62///
63/// let mut buf = OwnedBuf::with_alignment::<u8>();
64/// let bytes = buf.store_unsized(&b"Hello World!"[..])?;
65/// assert_eq!(buf.load(bytes)?, b"Hello World!");
66/// # Ok::<_, musli_zerocopy::Error>(())
67/// ```
68pub unsafe trait UnsizedZeroCopy: self::sealed::Sealed + Pointee {
69    /// Alignment of the pointed-to data
70    const ALIGN: usize;
71
72    /// If the pointed-to data contains any padding.
73    const PADDED: bool;
74
75    /// Return a pointer to the base of the pointed-to value.
76    fn as_ptr(&self) -> *const u8;
77
78    /// Metadata associated with the unsized value that is embedded in the
79    /// pointer.
80    fn metadata(&self) -> Self::Metadata;
81
82    /// Apply padding as per the pointed-to value.
83    unsafe fn pad(&self, pad: &mut Padder<'_, Self>);
84
85    /// Validate the buffer with the given capacity and return the decoded
86    /// metadata.
87    ///
88    /// # Safety
89    ///
90    /// The caller must guarantee that `data` point to a buffer that is at least
91    /// `len` long containing initialized data.
92    unsafe fn validate_unsized<E, O>(
93        data: NonNull<u8>,
94        len: usize,
95        metadata: Self::Stored<O>,
96    ) -> Result<Self::Metadata, Error>
97    where
98        E: ByteOrder,
99        O: Size;
100
101    /// Construct a wide pointer from a pointer and its associated metadata.
102    ///
103    /// Note that calling this method is not unsafe, however using the resulting
104    /// pointer as an inhabitant of the given type without it being validated
105    /// first using [`validate_unsized()`] unsound.
106    ///
107    /// [`validate_unsized()`]: Self::validate_unsized
108    fn with_metadata(data: NonNull<u8>, metadata: Self::Metadata) -> *const Self;
109
110    /// Construct a wide mutable pointer from a pointer and its associated
111    /// metadata.
112    ///
113    /// Note that calling this method is not unsafe, however using the resulting
114    /// pointer as an inhabitant of the given type without it being validated
115    /// first using [`validate_unsized()`] unsound.
116    ///
117    /// [`validate_unsized()`]: Self::validate_unsized
118    fn with_metadata_mut(data: NonNull<u8>, metadata: Self::Metadata) -> *mut Self;
119}
120
121/// This is a marker trait that must be implemented for a type in order to use
122/// the `#[zero_copy(ignore)]` attribute when deriving the [`ZeroCopy`] trait.
123///
124/// Using the attribute incorrectly might lead to unsoundness.
125///
126/// # Safety
127///
128/// Any type implementing this trait must be zero-sized.
129///
130/// # Examples
131///
132/// Using `#[zero_copy(ignore)]` on generic fields that implements
133/// [`ZeroSized`]:
134///
135/// ```
136/// use musli_zerocopy::{ZeroCopy, ZeroSized};
137///
138/// #[derive(ZeroCopy)]
139/// #[repr(transparent)]
140/// struct Struct<T> where T: ZeroSized {
141///     #[zero_copy(ignore)]
142///     field: T,
143/// }
144/// ```
145///
146/// Types which derive [`ZeroCopy`] also implement [`ZeroSized`] if they are
147/// zero-sized:
148///
149/// ```
150/// use std::marker::PhantomData;
151/// use std::mem::size_of;
152///
153/// use musli_zerocopy::{ZeroCopy, ZeroSized};
154///
155/// #[derive(ZeroCopy)]
156/// #[repr(transparent)]
157/// struct Struct<T> where T: ZeroSized {
158///     #[zero_copy(ignore)]
159///     field: T,
160/// }
161///
162/// #[derive(ZeroCopy)]
163/// #[repr(transparent)]
164/// struct OtherStruct {
165///     #[zero_copy(ignore)]
166///     field: Struct<()>,
167/// }
168///
169/// fn assert_zero_sized<T: ZeroSized>() {
170///     assert_eq!(size_of::<T>(), 0);
171/// }
172///
173/// assert_zero_sized::<()>();
174/// assert_zero_sized::<PhantomData<u32>>();
175/// assert_zero_sized::<OtherStruct>();
176/// assert_zero_sized::<Struct<OtherStruct>>();
177/// ```
178pub unsafe trait ZeroSized {}
179
180/// [`ZeroCopy`] implementation for `Wrapping<T>`.
181///
182/// # Examples
183///
184/// ```
185/// use std::num::Wrapping;
186///
187/// use musli_zerocopy::{buf, Ref, ZeroCopy};
188///
189/// #[derive(ZeroCopy)]
190/// #[repr(C)]
191/// struct Struct {
192///     field: Wrapping<u32>,
193/// }
194///
195/// let zero = u32::to_ne_bytes(0);
196/// let zero = buf::aligned_buf::<u32>(&zero)?;
197/// let one = u32::to_ne_bytes(1);
198/// let one = buf::aligned_buf::<u32>(&one)?;
199///
200/// let st = zero.load(Ref::<Struct>::zero())?;
201/// assert_eq!(st.field.0, 0);
202///
203/// let st = one.load(Ref::<Struct>::zero())?;
204/// assert_eq!(st.field.0, 1);
205/// # Ok::<_, musli_zerocopy::Error>(())
206/// ```
207// SAFETY: `Wrapping<T>` is repr-transparent.
208unsafe impl<T> ZeroSized for Wrapping<T> where T: ZeroSized {}
209
210unsafe impl<T> ZeroCopy for Wrapping<T>
211where
212    T: ZeroCopy,
213{
214    const ANY_BITS: bool = T::ANY_BITS;
215    const PADDED: bool = T::PADDED;
216    const CAN_SWAP_BYTES: bool = T::CAN_SWAP_BYTES;
217
218    #[inline]
219    unsafe fn pad(padder: &mut Padder<'_, Self>) {
220        unsafe {
221            padder.pad::<T>();
222        }
223    }
224
225    #[inline]
226    unsafe fn validate(validator: &mut Validator<'_, Self>) -> Result<(), Error> {
227        unsafe { validator.validate::<T>() }
228    }
229
230    #[inline]
231    fn swap_bytes<E>(self) -> Self
232    where
233        E: ByteOrder,
234    {
235        Wrapping(T::swap_bytes::<E>(self.0))
236    }
237}
238
239/// `()` can be ignored as a zero-sized field.
240///
241/// # Examples
242///
243/// ```
244/// use musli_zerocopy::ZeroCopy;
245///
246/// #[derive(ZeroCopy)]
247/// #[repr(transparent)]
248/// struct Struct {
249///     #[zero_copy(ignore)]
250///     field: (),
251/// }
252/// ```
253// SAFETY: `()` is zero-sized.
254unsafe impl ZeroSized for () {}
255
256/// `[T; 0]` can be ignored as a zero-sized field.
257///
258/// # Examples
259///
260/// ```
261/// use musli_zerocopy::ZeroCopy;
262///
263/// #[derive(ZeroCopy)]
264/// #[repr(transparent)]
265/// struct Struct<T> {
266///     #[zero_copy(ignore)]
267///     field: [T; 0],
268/// }
269/// ```
270// SAFETY: `[T; 0]` is zero-sized.
271unsafe impl<T> ZeroSized for [T; 0] {}
272
273/// `PhantomData<T>` can be ignored as a zero-sized field.
274///
275/// # Examples
276///
277/// ```
278/// use std::marker::PhantomData;
279/// use musli_zerocopy::ZeroCopy;
280///
281/// #[derive(ZeroCopy)]
282/// #[repr(transparent)]
283/// struct Struct<T> {
284///     #[zero_copy(ignore)]
285///     field: PhantomData<T>,
286/// }
287/// ```
288// SAFETY: `PhantomData<T>` is zero-sized.
289unsafe impl<T: ?Sized> ZeroSized for PhantomData<T> {}
290
291/// Trait governing types can be safely coerced into a reference from a buffer.
292///
293/// It is not recommended to implement this trait manually, instead rely on the
294/// [`ZeroCopy`] derive.
295///
296/// [`ZeroCopy`]: derive@crate::ZeroCopy
297///
298/// # Safety
299///
300/// This can only be implemented correctly by types under certain conditions:
301/// * The type has a strict, well-defined layout like `repr(C)` or an enum with
302///   `repr(u32)`.
303/// * It's size and alignment must be known statically as per [`size_of`] and
304///   [`align_of`]. This excludes enums which are `#[repr(C)]` because for
305///   example their alignment depends on the range of values they can represent.
306///
307/// [`size_of`]: core::mem::size_of
308///
309/// # Notable types which cannot be `ZeroCopy`
310///
311/// Any type which does not have an explicit representation cannot implement
312/// `ZeroCopy`. Most Rust types use the Rust. Or `#[repr(Rust)]`. The Rust as a
313/// language is allowed to make arbitrary layout decisions for `#[repr(Rust)]`
314/// types.
315///
316/// The following is a list of common Rust types which *cannot* implements
317/// `ZeroCopy`, and the rationale for why:
318///
319/// * Non-zero sized tuples. Since tuples do not have a stable layout.
320/// * `Option<T>` since that is a `#[repr(Rust)]` type, except where [specific
321///   representation guarantees] are made such as with `Option<NonZero*>` types.
322///
323/// [specific representation guarantees]:
324///     https://doc.rust-lang.org/std/option/index.html#representation
325///
326/// # Examples
327///
328/// Using [`to_bytes`], [`from_bytes`], and [`from_bytes_mut`]:
329///
330/// [`to_bytes`]: Self::to_bytes
331/// [`from_bytes`]: Self::from_bytes
332/// [`from_bytes_mut`]: Self::from_bytes_mut
333///
334/// ```
335/// use musli_zerocopy::{buf, ZeroCopy};
336///
337/// #[derive(ZeroCopy, Debug, PartialEq)]
338/// #[repr(C)]
339/// struct Weapon {
340///     id: u8,
341///     damage: u32,
342/// }
343///
344/// let mut weapon = Weapon {
345///     id: 1,
346///     damage: 42u32,
347/// };
348///
349/// let original = weapon.to_bytes_padded();
350///
351/// // Make a copy that we can play around with.
352/// let mut bytes = buf::aligned_buf::<Weapon>(original)?.into_owned();
353///
354/// assert_eq!(weapon.damage, 42);
355/// assert_eq!(&weapon, Weapon::from_bytes(&bytes[..])?);
356///
357/// assert_eq!(&bytes[0..1], [1]);
358/// assert_eq!(&bytes[4..8], 42u32.to_ne_bytes());
359///
360/// // SAFETY: Modifying a field of a u32 does not leave any uninitialized space.
361/// unsafe {
362///     let weapon = Weapon::from_bytes_mut_padded(bytes.as_mut_slice())?;
363///     weapon.damage += 10;
364/// }
365///
366/// assert_eq!(&bytes[0..1], [1]);
367/// assert_eq!(&bytes[4..8], 52u32.to_ne_bytes());
368/// # Ok::<_, musli_zerocopy::Error>(())
369/// ```
370///
371/// Unsafely access an immutable reference by manually padding the struct using
372/// [`initialize_padding()`] and [`to_bytes_unchecked()`]:
373///
374/// [`initialize_padding()`]: Self::initialize_padding
375/// [`to_bytes_unchecked()`]: Self::to_bytes_unchecked
376///
377/// ```
378/// use musli_zerocopy::ZeroCopy;
379/// # #[derive(ZeroCopy, Debug, PartialEq)]
380/// # #[repr(C)]
381/// # struct Weapon { id: u8, damage: u32 }
382///
383/// let mut weapon = Weapon {
384///     id: 1,
385///     damage: 42u32,
386/// };
387///
388/// weapon.initialize_padding();
389///
390/// // SAFETY: Padding for the type has been initialized, and the type has not been moved since it was padded.
391/// let bytes = unsafe { weapon.to_bytes_unchecked() };
392/// # #[cfg(target_endian = "little")]
393/// assert_eq!(bytes, &[1, 0, 0, 0, 42, 0, 0, 0]);
394/// assert_eq!(Weapon::from_bytes(&bytes)?, &weapon);
395/// # Ok::<_, musli_zerocopy::Error>(())
396/// ```
397///
398/// Interacting with an [`OwnedBuf`]:
399///
400/// [`OwnedBuf`]: crate::buf::OwnedBuf
401///
402/// ```
403/// use musli_zerocopy::{OwnedBuf, ZeroCopy};
404///
405/// #[derive(Debug, PartialEq, ZeroCopy)]
406/// #[repr(C)]
407/// struct Custom { field: u32, #[zero_copy(ignore)] ignore: () }
408///
409/// let mut buf = OwnedBuf::new();
410/// let ptr = buf.store(&Custom { field: 42, ignore: () })?;
411/// buf.align_in_place()?;
412/// assert_eq!(buf.load(ptr)?, &Custom { field: 42, ignore: () });
413/// # Ok::<_, musli_zerocopy::Error>(())
414/// ```
415pub unsafe trait ZeroCopy
416where
417    Self: Sized,
418{
419    /// Indicates if the type can inhabit all possible bit patterns within its
420    /// [`size_of::<Self>()`] bytes.
421    const ANY_BITS: bool;
422
423    /// Indicates if a type is padded.
424    const PADDED: bool;
425
426    /// Indicates if the type has a valid byte-ordered transformation.
427    ///
428    /// Most notably this is `false` for [`char`].
429    const CAN_SWAP_BYTES: bool;
430
431    /// Mark padding for the current type.
432    ///
433    /// The `this` receiver takes the current type as pointer instead of a
434    /// reference, because it might not be aligned in the case of packed types.
435    ///
436    /// # Safety
437    ///
438    /// The implementor is responsible for ensuring that every field is provided
439    /// to `padder`, including potentially hidden ones.
440    #[doc(hidden)]
441    unsafe fn pad(padder: &mut Padder<'_, Self>);
442
443    /// Validate the current type.
444    ///
445    /// # Safety
446    ///
447    /// This assumes that the provided validator is wrapping a buffer that is
448    /// appropriately sized and aligned.
449    #[doc(hidden)]
450    unsafe fn validate(validator: &mut Validator<'_, Self>) -> Result<(), Error>;
451
452    /// Ensure that the padding for the current value is initialized.
453    ///
454    /// This can be used in combination with [`to_bytes_unchecked()`] to relax
455    /// the borrowing requirement for [`to_bytes()`], but is `unsafe`.
456    ///
457    /// See the [type level documentation] for examples.
458    ///
459    /// [`to_bytes_unchecked()`]: Self::to_bytes_unchecked
460    /// [`to_bytes()`]: Self::to_bytes
461    /// [type level documentation]: Self
462    #[inline]
463    fn initialize_padding(&mut self) {
464        unsafe {
465            if Self::PADDED {
466                let ptr = NonNull::new_unchecked((self as *mut Self).cast::<MaybeUninit<u8>>());
467                let mut padder = Padder::new(ptr);
468                Self::pad(&mut padder);
469                padder.remaining();
470            }
471        }
472    }
473
474    /// Convert a mutable reference to a `ZeroCopy` type into bytes.
475    ///
476    /// See the [type level documentation] for examples.
477    ///
478    /// [`initialize_padding()`]: Self::initialize_padding
479    /// [type level documentation]: Self
480    ///
481    /// # Examples
482    ///
483    /// ```
484    /// use musli_zerocopy::ZeroCopy;
485    ///
486    /// #[derive(ZeroCopy, Debug, PartialEq)]
487    /// #[repr(C)]
488    /// struct Weapon {
489    ///     id: u8,
490    ///     damage: u32,
491    /// }
492    ///
493    /// let mut weapon = Weapon {
494    ///     id: 1,
495    ///     damage: 42,
496    /// };
497    ///
498    /// let bytes = weapon.to_bytes_padded();
499    /// assert_eq!(&bytes[0..1], [1]);
500    /// assert_eq!(&bytes[4..8], 42u32.to_ne_bytes());
501    /// ```
502    #[track_caller]
503    #[inline]
504    fn to_bytes(&self) -> &[u8] {
505        const {
506            assert!(
507                !Self::PADDED,
508                "ZeroCopy::to_bytes_unpadded can only be used on unpadded types"
509            );
510        }
511
512        unsafe { self.to_bytes_unchecked() }
513    }
514
515    /// Convert a reference to a `ZeroCopy` type into bytes assuming it might be
516    /// [`Self::PADDED`].
517    ///
518    /// This requires mutable access to `self`, since it must call
519    /// [`initialize_padding()`] to ensure that the returned buffer is fully
520    /// initialized.
521    ///
522    /// See the [type level documentation] for examples.
523    ///
524    /// [`initialize_padding()`]: Self::initialize_padding
525    /// [type level documentation]: Self
526    ///
527    /// # Examples
528    ///
529    /// ```
530    /// use musli_zerocopy::ZeroCopy;
531    ///
532    /// let mut value = 42u32;
533    /// assert_eq!(value.to_bytes(), 42u32.to_ne_bytes());
534    /// # Ok::<_, musli_zerocopy::Error>(())
535    /// ```
536    #[inline]
537    fn to_bytes_padded(&mut self) -> &[u8] {
538        self.initialize_padding();
539
540        unsafe { self.to_bytes_unchecked() }
541    }
542
543    /// Convert a `ZeroCopy` type into bytes.
544    ///
545    /// This does not require mutable access to `self`, but the caller must
546    /// ensure that [`initialize_padding()`] has been called at some point before this
547    /// function and that the type that was padded has not been moved.
548    ///
549    /// See the [type level documentation] for examples.
550    ///
551    /// [`initialize_padding()`]: Self::initialize_padding
552    /// [type level documentation]: Self
553    #[inline]
554    unsafe fn to_bytes_unchecked(&self) -> &[u8] {
555        unsafe {
556            let ptr = (self as *const Self).cast::<u8>();
557            slice::from_raw_parts(ptr, size_of::<Self>())
558        }
559    }
560
561    /// Convert a mutable reference to a `ZeroCopy` type into mutable bytes
562    /// requring `!Self::PADDED`.
563    ///
564    /// See the [type level documentation] for examples.
565    ///
566    /// [type level documentation]: Self
567    ///
568    /// # Examples
569    ///
570    /// ```
571    /// use musli_zerocopy::ZeroCopy;
572    ///
573    /// #[derive(ZeroCopy)]
574    /// #[repr(C)]
575    /// struct Packed {
576    ///     a: u32,
577    ///     b: u32,
578    /// }
579    ///
580    /// let mut value = Packed { a: 1, b: 42 };
581    /// value.initialize_padding();
582    ///
583    /// let bytes = value.to_bytes_mut();
584    ///
585    /// assert_eq!(&bytes[0..4], 1u32.to_ne_bytes());
586    /// assert_eq!(&bytes[4..8], 42u32.to_ne_bytes());
587    ///
588    /// let value = Packed::from_bytes_mut(&mut *bytes)?;
589    /// value.a = 2;
590    /// value.initialize_padding();
591    ///
592    /// assert_eq!(&bytes[0..4], 2u32.to_ne_bytes());
593    /// assert_eq!(&bytes[4..8], 42u32.to_ne_bytes());
594    /// # Ok::<_, musli_zerocopy::Error>(())
595    /// ```
596    #[track_caller]
597    #[inline]
598    fn to_bytes_mut(&mut self) -> &mut [u8] {
599        const {
600            assert!(
601                !Self::PADDED,
602                "ZeroCopy::to_bytes_unpadded can only be used on unpadded types"
603            );
604        }
605
606        unsafe { self.to_bytes_mut_unchecked() }
607    }
608
609    /// Convert a mutable reference to a `ZeroCopy` type into mutable bytes
610    /// assuming it might be [`Self::PADDED`].
611    ///
612    /// This will call [`initialize_padding()`] to ensure that the returned bit
613    /// pattern is initialized.
614    ///
615    /// See the [type level documentation] for examples.
616    ///
617    /// [`initialize_padding()`]: Self::initialize_padding
618    /// [type level documentation]: Self
619    ///
620    /// # Examples
621    ///
622    /// ```
623    /// use musli_zerocopy::ZeroCopy;
624    ///
625    /// #[derive(ZeroCopy)]
626    /// #[repr(C)]
627    /// struct Weapon {
628    ///     id: u8,
629    ///     damage: u32,
630    /// }
631    ///
632    /// let mut value = Weapon { id: 1, damage: 42 };
633    /// value.initialize_padding();
634    ///
635    /// let bytes = value.to_bytes_mut_padded();
636    ///
637    /// assert_eq!(&bytes[0..1], [1]);
638    /// assert_eq!(&bytes[4..8], 42u32.to_ne_bytes());
639    ///
640    /// // SAFETY: After writing to the id field, we initialize padding again to
641    /// // ensure we can safely access the used buffer again.
642    /// unsafe {
643    ///     let value = Weapon::from_bytes_mut_padded(&mut *bytes)?;
644    ///     value.id = 2;
645    ///     value.initialize_padding();
646    /// }
647    ///
648    /// assert_eq!(&bytes[0..1], [2]);
649    /// assert_eq!(&bytes[4..8], 42u32.to_ne_bytes());
650    /// # Ok::<_, musli_zerocopy::Error>(())
651    /// ```
652    #[inline]
653    fn to_bytes_mut_padded(&mut self) -> &mut [u8] {
654        self.initialize_padding();
655
656        unsafe { self.to_bytes_mut_unchecked() }
657    }
658
659    /// Convert a `ZeroCopy` type into mutable bytes.
660    ///
661    /// See the [type level documentation] for examples.
662    ///
663    /// [`initialize_padding()`]: Self::initialize_padding
664    /// [type level documentation]: Self
665    #[inline]
666    unsafe fn to_bytes_mut_unchecked(&mut self) -> &mut [u8] {
667        unsafe {
668            let ptr = (self as *mut Self).cast::<u8>();
669            slice::from_raw_parts_mut(ptr, size_of::<Self>())
670        }
671    }
672
673    /// Load bytes into a reference of `Self`.
674    ///
675    /// See the [type level documentation] for examples.
676    ///
677    /// [type level documentation]: Self
678    ///
679    /// # Errors
680    ///
681    /// This will ensure that `bytes` is aligned, appropriately sized, and valid
682    /// to inhabit `&Self`. Anything else will cause an [`Error`] detailing why
683    /// the conversion failed.
684    ///
685    /// # Examples
686    ///
687    /// ```
688    /// use musli_zerocopy::{OwnedBuf, ZeroCopy};
689    ///
690    /// let mut buf = OwnedBuf::new();
691    /// buf.extend_from_slice(&1u32.to_ne_bytes())?;
692    ///
693    /// let bytes: &[u8] = &buf[..];
694    /// assert_eq!(*u32::from_bytes(&bytes)?, 1);
695    /// # Ok::<_, musli_zerocopy::Error>(())
696    /// ```
697    #[inline]
698    fn from_bytes(bytes: &[u8]) -> Result<&Self, Error> {
699        Buf::new(bytes).load_at::<Self>(0)
700    }
701
702    /// Load bytes into a mutable reference of `Self`.
703    ///
704    /// See the [type level documentation] for examples.
705    ///
706    /// [type level documentation]: Self
707    ///
708    /// # Errors
709    ///
710    /// This will ensure that `bytes` is aligned, appropriately sized, and valid
711    /// to inhabit `&mut Self`. Anything else will cause an [`Error`] detailing
712    /// why the conversion failed.
713    ///
714    /// See [`Buf::new_mut`] for more information.
715    ///
716    /// # Examples
717    ///
718    /// ```
719    /// use musli_zerocopy::{OwnedBuf, ZeroCopy};
720    ///
721    /// let mut buf = OwnedBuf::new();
722    /// buf.extend_from_slice(&1u32.to_ne_bytes())?;
723    ///
724    /// *u32::from_bytes_mut(buf.as_mut_slice())? += 10;
725    ///
726    /// assert_eq!(*u32::from_bytes(&buf[..])?, 11);
727    /// # Ok::<_, musli_zerocopy::Error>(())
728    /// ```
729    #[track_caller]
730    #[inline]
731    fn from_bytes_mut(bytes: &mut [u8]) -> Result<&mut Self, Error> {
732        const {
733            assert!(
734                !Self::PADDED,
735                "ZeroCopy::from_bytes_mut can only be used on unpadded types"
736            );
737        }
738
739        unsafe { Buf::new_mut(bytes).load_at_mut::<Self>(0) }
740    }
741
742    /// Load bytes into a mutable reference of `Self` assuming it is
743    /// [`Self::PADDED`].
744    ///
745    /// See the [type level documentation] for examples.
746    ///
747    /// [type level documentation]: Self
748    ///
749    /// # Errors
750    ///
751    /// This will ensure that `bytes` is aligned, appropriately sized, and valid
752    /// to inhabit `&mut Self`. Anything else will cause an [`Error`] detailing
753    /// why the conversion failed.
754    ///
755    /// See [`Buf::new_mut`] for more information.
756    ///
757    /// # Examples
758    ///
759    /// ```
760    /// use musli_zerocopy::{OwnedBuf, ZeroCopy};
761    ///
762    /// let mut buf = OwnedBuf::new();
763    /// buf.extend_from_slice(&1u32.to_ne_bytes())?;
764    ///
765    /// // SAFETY: Writing a u32 does not leave any uninitialized space.
766    /// unsafe {
767    ///     *u32::from_bytes_mut(buf.as_mut_slice())? += 10;
768    /// }
769    ///
770    /// assert_eq!(*u32::from_bytes(&buf[..])?, 11);
771    /// # Ok::<_, musli_zerocopy::Error>(())
772    /// ```
773    ///
774    /// Use with a padded type:
775    ///
776    /// ```
777    /// use musli_zerocopy::ZeroCopy;
778    ///
779    /// #[derive(ZeroCopy)]
780    /// #[repr(C)]
781    /// struct Weapon {
782    ///     id: u8,
783    ///     damage: u32,
784    /// }
785    ///
786    /// let mut value = Weapon { id: 1, damage: 42 };
787    /// value.initialize_padding();
788    ///
789    /// let bytes = value.to_bytes_mut_padded();
790    ///
791    /// assert_eq!(&bytes[0..1], [1]);
792    /// assert_eq!(&bytes[4..8], 42u32.to_ne_bytes());
793    ///
794    /// // SAFETY: After writing to the id field, we initialize padding again to
795    /// // ensure we can safely access the used buffer again.
796    /// unsafe {
797    ///     let value = Weapon::from_bytes_mut_padded(&mut *bytes)?;
798    ///     value.id = 2;
799    ///     value.initialize_padding();
800    /// }
801    ///
802    /// assert_eq!(&bytes[0..1], [2]);
803    /// assert_eq!(&bytes[4..8], 42u32.to_ne_bytes());
804    /// # Ok::<_, musli_zerocopy::Error>(())
805    /// ```
806    #[track_caller]
807    #[inline]
808    unsafe fn from_bytes_mut_padded(bytes: &mut [u8]) -> Result<&mut Self, Error> {
809        unsafe { Buf::new_mut(bytes).load_at_mut::<Self>(0) }
810    }
811
812    /// Swap the bytes of `self` using the specified byte ordering to match the
813    /// native byte ordering.
814    ///
815    /// If the specified [`ByteOrder`] matches the current ordering, this is a
816    /// no-op.
817    ///
818    /// This will cause any byte-order sensitive primitives to be converted to
819    /// the native byte order.
820    ///
821    /// # Complex types
822    ///
823    /// For complex types, this will walk the type hierarchy and swap each
824    /// composite field that is apart of that type.
825    ///
826    /// ```
827    /// use musli_zerocopy::{endian, Ref, ZeroCopy};
828    ///
829    /// #[derive(ZeroCopy)]
830    /// #[repr(C)]
831    /// struct Struct {
832    ///     number: u32,
833    ///     reference: Ref<u32, endian::Little, usize>,
834    /// }
835    ///
836    /// let st = Struct {
837    ///     number: 0x10203040u32.to_le(),
838    ///     reference: Ref::new(0x50607080usize.to_le()),
839    /// };
840    ///
841    /// assert_eq!(st.number, 0x10203040u32.to_le());
842    /// assert_eq!(st.reference.offset(), 0x50607080usize);
843    ///
844    /// let st2 = st.swap_bytes::<endian::Big>();
845    /// assert_eq!(st2.number, 0x10203040u32.to_be());
846    /// assert_eq!(st2.reference.offset(), 0x50607080usize);
847    /// ```
848    ///
849    /// # Safety
850    ///
851    /// There's nothing fundamentally unsafe about byte swapping, all though it
852    /// should be noted that the exact output is not guaranteed to be stable in
853    /// case a type cannot be safely byte-swapped. This is the case for
854    /// [`char`], since byte swapping one might cause it to inhabit an illegal
855    /// bit pattern.
856    ///
857    /// To test whether a type can be byte swapped, the [`CAN_SWAP_BYTES`]
858    /// constant should be advised.
859    ///
860    /// [`CAN_SWAP_BYTES`]: Self::CAN_SWAP_BYTES
861    fn swap_bytes<E>(self) -> Self
862    where
863        E: ByteOrder;
864}
865
866unsafe impl UnsizedZeroCopy for str {
867    const ALIGN: usize = align_of::<u8>();
868    const PADDED: bool = false;
869
870    #[inline]
871    fn as_ptr(&self) -> *const u8 {
872        str::as_ptr(self)
873    }
874
875    #[inline]
876    fn metadata(&self) -> Self::Metadata {
877        str::len(self)
878    }
879
880    #[inline]
881    unsafe fn pad(&self, _: &mut Padder<'_, Self>) {}
882
883    #[inline]
884    unsafe fn validate_unsized<E, O>(
885        data: NonNull<u8>,
886        len: usize,
887        metadata: Self::Stored<O>,
888    ) -> Result<Self::Metadata, Error>
889    where
890        E: ByteOrder,
891        O: Size,
892    {
893        let metadata = metadata.swap_bytes::<E>().as_usize();
894
895        if metadata > len {
896            return Err(Error::new(ErrorKind::OutOfRangeBounds {
897                range: 0..metadata,
898                len,
899            }));
900        };
901
902        let buf = unsafe { slice::from_raw_parts(data.as_ptr(), metadata) };
903        str::from_utf8(buf).map_err(|error| Error::new(ErrorKind::Utf8Error { error }))?;
904        Ok(metadata)
905    }
906
907    #[inline]
908    fn with_metadata(data: NonNull<u8>, metadata: Self::Metadata) -> *const Self {
909        let slice = ptr::slice_from_raw_parts(data.as_ptr(), metadata);
910        slice as *const Self
911    }
912
913    #[inline]
914    fn with_metadata_mut(data: NonNull<u8>, metadata: Self::Metadata) -> *mut Self {
915        let slice = ptr::slice_from_raw_parts_mut(data.as_ptr(), metadata);
916        slice as *mut Self
917    }
918}
919
920unsafe impl<T> UnsizedZeroCopy for [T]
921where
922    T: ZeroCopy,
923{
924    const ALIGN: usize = align_of::<T>();
925    const PADDED: bool = T::PADDED;
926
927    #[inline]
928    fn as_ptr(&self) -> *const u8 {
929        <[T]>::as_ptr(self).cast()
930    }
931
932    #[inline]
933    unsafe fn pad(&self, padder: &mut Padder<'_, Self>) {
934        for _ in 0..self.len() {
935            unsafe {
936                padder.pad::<T>();
937            }
938        }
939    }
940
941    #[inline]
942    fn metadata(&self) -> Self::Metadata {
943        self.len()
944    }
945
946    #[inline]
947    unsafe fn validate_unsized<E, O>(
948        data: NonNull<u8>,
949        len: usize,
950        metadata: Self::Stored<O>,
951    ) -> Result<Self::Metadata, Error>
952    where
953        E: ByteOrder,
954        O: Size,
955    {
956        let metadata = metadata.swap_bytes::<E>().as_usize();
957
958        let Some(size) = metadata.checked_mul(size_of::<T>()) else {
959            return Err(Error::from(CoerceError::new(
960                CoerceErrorKind::LengthOverflow {
961                    len: metadata,
962                    size: size_of::<T>(),
963                },
964            )));
965        };
966
967        if size > len {
968            return Err(Error::new(ErrorKind::OutOfRangeBounds {
969                range: 0..metadata,
970                len,
971            }));
972        };
973
974        if !T::ANY_BITS {
975            unsafe {
976                let mut validator = Validator::<[T]>::new(data);
977
978                for _ in 0..metadata {
979                    validator.validate_only::<T>()?;
980                }
981            }
982        }
983
984        Ok(metadata)
985    }
986
987    #[inline]
988    fn with_metadata(data: NonNull<u8>, metadata: Self::Metadata) -> *const Self {
989        ptr::slice_from_raw_parts(data.cast().as_ptr(), metadata)
990    }
991
992    #[inline]
993    fn with_metadata_mut(data: NonNull<u8>, metadata: Self::Metadata) -> *mut Self {
994        ptr::slice_from_raw_parts_mut(data.cast().as_ptr(), metadata)
995    }
996}
997
998macro_rules! impl_number {
999    ($ty:ty, $from_be:path) => {
1000        #[doc = concat!(" [`ZeroCopy`] implementation for `", stringify!($ty), "`")]
1001        ///
1002        /// # Examples
1003        ///
1004        /// ```
1005        /// use std::slice;
1006        /// use std::mem::size_of;
1007        /// use musli_zerocopy::{buf, Ref, ZeroCopy};
1008        ///
1009        /// #[derive(ZeroCopy)]
1010        /// #[repr(C)]
1011        /// struct Struct {
1012        #[doc = concat!("    field: ", stringify!($ty), ",")]
1013        /// }
1014        ///
1015        #[doc = concat!("let zero: ", stringify!($ty), " = 0;")]
1016        #[doc = concat!("let one: ", stringify!($ty), " = 1;")]
1017        ///
1018        #[doc = concat!("let zero = ", stringify!($ty), "::to_ne_bytes(0);")]
1019        #[doc = concat!("let zero = buf::aligned_buf::<", stringify!($ty), ">(&zero)?;")]
1020        #[doc = concat!("let one = ", stringify!($ty), "::to_ne_bytes(1);")]
1021        #[doc = concat!("let one = buf::aligned_buf::<", stringify!($ty), ">(&one)?;")]
1022        ///
1023        /// let st = zero.load(Ref::<Struct>::zero())?;
1024        /// assert_eq!(st.field, 0);
1025        ///
1026        /// let st = one.load(Ref::<Struct>::zero())?;
1027        /// assert_eq!(st.field, 1);
1028        /// # Ok::<_, musli_zerocopy::Error>(())
1029        /// ```
1030        unsafe impl ZeroCopy for $ty {
1031            const ANY_BITS: bool = true;
1032            const PADDED: bool = false;
1033            const CAN_SWAP_BYTES: bool = true;
1034
1035            #[inline]
1036            unsafe fn pad(_: &mut Padder<'_, Self>) {}
1037
1038            #[inline]
1039            unsafe fn validate(_: &mut Validator<'_, Self>) -> Result<(), Error> {
1040                Ok(())
1041            }
1042
1043            #[inline]
1044            fn swap_bytes<E>(self) -> Self
1045            where
1046                E: ByteOrder,
1047            {
1048                $from_be(self)
1049            }
1050        }
1051
1052        impl Visit for $ty {
1053            type Target = $ty;
1054
1055            #[inline]
1056            fn visit<V, O>(&self, _: &Buf, visitor: V) -> Result<O, Error>
1057            where
1058                V: FnOnce(&Self::Target) -> O,
1059            {
1060                Ok(visitor(self))
1061            }
1062        }
1063    };
1064}
1065
1066impl_number!(usize, E::swap_usize);
1067impl_number!(isize, E::swap_isize);
1068impl_number!(u8, E::swap_u8);
1069impl_number!(u16, E::swap_u16);
1070impl_number!(u32, E::swap_u32);
1071impl_number!(u64, E::swap_u64);
1072impl_number!(u128, E::swap_u128);
1073impl_number!(i8, E::swap_i8);
1074impl_number!(i16, E::swap_i16);
1075impl_number!(i32, E::swap_i32);
1076impl_number!(i64, E::swap_i64);
1077impl_number!(i128, E::swap_i128);
1078
1079macro_rules! impl_float {
1080    ($ty:ty, $from_fn:path) => {
1081        unsafe impl ZeroCopy for $ty {
1082            const ANY_BITS: bool = true;
1083            const PADDED: bool = false;
1084            const CAN_SWAP_BYTES: bool = true;
1085
1086            #[inline]
1087            unsafe fn pad(_: &mut Padder<'_, Self>) {}
1088
1089            #[inline]
1090            unsafe fn validate(_: &mut Validator<'_, Self>) -> Result<(), Error> {
1091                Ok(())
1092            }
1093
1094            fn swap_bytes<E>(self) -> Self
1095            where
1096                E: ByteOrder,
1097            {
1098                $from_fn(self)
1099            }
1100        }
1101
1102        impl Visit for $ty {
1103            type Target = $ty;
1104
1105            #[inline]
1106            fn visit<V, O>(&self, _: &Buf, visitor: V) -> Result<O, Error>
1107            where
1108                V: FnOnce(&Self::Target) -> O,
1109            {
1110                Ok(visitor(self))
1111            }
1112        }
1113    };
1114}
1115
1116impl_float!(f32, E::swap_f32);
1117impl_float!(f64, E::swap_f64);
1118
1119/// The `ZeroCopy` implementation for `char`.
1120///
1121/// Validating this type is byte-order sensitive, since the bit-pattern it
1122/// inhabits needs to align with the bit-patterns it can inhabit.
1123unsafe impl ZeroCopy for char {
1124    const ANY_BITS: bool = false;
1125    const PADDED: bool = false;
1126    const CAN_SWAP_BYTES: bool = false;
1127
1128    #[inline]
1129    unsafe fn pad(_: &mut Padder<'_, Self>) {}
1130
1131    #[inline]
1132    unsafe fn validate(validator: &mut Validator<'_, Self>) -> Result<(), Error> {
1133        let repr = unsafe { validator.load_unaligned::<u32>()? };
1134
1135        if char::try_from(repr).is_err() {
1136            return Err(Error::new(ErrorKind::InvalidCharRepr { repr }));
1137        }
1138
1139        Ok(())
1140    }
1141
1142    #[inline]
1143    fn swap_bytes<E>(self) -> Self
1144    where
1145        E: ByteOrder,
1146    {
1147        self
1148    }
1149}
1150
1151impl Visit for char {
1152    type Target = char;
1153
1154    #[inline]
1155    fn visit<V, O>(&self, _: &Buf, visitor: V) -> Result<O, Error>
1156    where
1157        V: FnOnce(&Self::Target) -> O,
1158    {
1159        Ok(visitor(self))
1160    }
1161}
1162
1163unsafe impl ZeroCopy for bool {
1164    const ANY_BITS: bool = false;
1165    const PADDED: bool = false;
1166    const CAN_SWAP_BYTES: bool = true;
1167
1168    #[inline]
1169    unsafe fn pad(_: &mut Padder<'_, Self>) {}
1170
1171    #[inline]
1172    unsafe fn validate(validator: &mut Validator<'_, Self>) -> Result<(), Error> {
1173        let b = unsafe { validator.byte() };
1174
1175        match b {
1176            0 | 1 => (),
1177            repr => return Err(Error::new(ErrorKind::InvalidBoolRepr { repr })),
1178        }
1179
1180        Ok(())
1181    }
1182
1183    #[inline]
1184    fn swap_bytes<E>(self) -> Self
1185    where
1186        E: ByteOrder,
1187    {
1188        self
1189    }
1190}
1191
1192impl Visit for bool {
1193    type Target = bool;
1194
1195    #[inline]
1196    fn visit<V, O>(&self, _: &Buf, visitor: V) -> Result<O, Error>
1197    where
1198        V: FnOnce(&Self::Target) -> O,
1199    {
1200        Ok(visitor(self))
1201    }
1202}
1203
1204macro_rules! impl_nonzero_number {
1205    ($ty:ident, $inner:ty) => {
1206        #[doc = concat!(" [`ZeroCopy`] implementation for `", stringify!($ty), "`")]
1207        ///
1208        /// # Examples
1209        ///
1210        /// ```
1211        #[doc = concat!("use std::num::", stringify!($ty), ";")]
1212        /// use std::slice;
1213        /// use std::mem::size_of;
1214        /// use musli_zerocopy::{buf, Ref, ZeroCopy};
1215        ///
1216        /// #[derive(ZeroCopy)]
1217        /// #[repr(C)]
1218        /// struct Struct {
1219        #[doc = concat!("    field: ", stringify!($ty), ",")]
1220        /// }
1221        ///
1222        #[doc = concat!("let zero = ", stringify!($inner), "::to_ne_bytes(0);")]
1223        #[doc = concat!("let zero = buf::aligned_buf::<", stringify!($ty), ">(&zero)?;")]
1224        #[doc = concat!("let one = ", stringify!($inner), "::to_ne_bytes(1);")]
1225        #[doc = concat!("let one = buf::aligned_buf::<", stringify!($ty), ">(&one)?;")]
1226        ///
1227        /// // Non-zero buffer works as expected.
1228        /// let st = one.load(Ref::<Struct>::zero())?;
1229        /// assert_eq!(st.field.get(), 1);
1230        ///
1231        /// // Trying to use a zeroed buffer with a non-zero type.
1232        /// assert!(zero.load(Ref::<Struct>::zero()).is_err());
1233        /// # Ok::<_, musli_zerocopy::Error>(())
1234        /// ```
1235        unsafe impl ZeroCopy for ::core::num::$ty {
1236            const ANY_BITS: bool = false;
1237            const PADDED: bool = false;
1238            const CAN_SWAP_BYTES: bool = true;
1239
1240            #[inline]
1241            unsafe fn pad(_: &mut Padder<'_, Self>) {}
1242
1243            #[inline]
1244            unsafe fn validate(validator: &mut Validator<'_, Self>) -> Result<(), Error> {
1245                let value = unsafe { validator.load_unaligned::<$inner>()? };
1246
1247                // NB: A zeroed bit-pattern is byte-order independent.
1248                if value == 0 {
1249                    return Err(Error::new(ErrorKind::NonZeroZeroed {
1250                        range: validator.range::<::core::num::$ty>(),
1251                    }));
1252                }
1253
1254                Ok(())
1255            }
1256
1257            #[inline]
1258            fn swap_bytes<E>(self) -> Self
1259            where
1260                E: ByteOrder,
1261            {
1262                // SAFETY: a value inhabiting zero is byte-order independent.
1263                unsafe {
1264                    ::core::num::$ty::new_unchecked(<$inner as ZeroCopy>::swap_bytes::<E>(
1265                        self.get(),
1266                    ))
1267                }
1268            }
1269        }
1270
1271        impl Visit for ::core::num::$ty {
1272            type Target = ::core::num::$ty;
1273
1274            #[inline]
1275            fn visit<V, O>(&self, _: &Buf, visitor: V) -> Result<O, Error>
1276            where
1277                V: FnOnce(&Self::Target) -> O,
1278            {
1279                Ok(visitor(self))
1280            }
1281        }
1282
1283        #[doc = concat!(" [`ZeroCopy`] implementation for `Option<", stringify!($ty), ">`")]
1284        ///
1285        /// # Examples
1286        ///
1287        /// ```
1288        #[doc = concat!("use std::num::", stringify!($ty), ";")]
1289        /// use std::slice;
1290        /// use std::mem::size_of;
1291        /// use musli_zerocopy::{buf, Ref, ZeroCopy};
1292        ///
1293        /// #[derive(ZeroCopy)]
1294        /// #[repr(C)]
1295        /// struct Struct {
1296        #[doc = concat!("    field: Option<", stringify!($ty), ">,")]
1297        /// }
1298        ///
1299        #[doc = concat!("let zero = ", stringify!($inner), "::to_ne_bytes(0);")]
1300        #[doc = concat!("let zero = buf::aligned_buf::<", stringify!($ty), ">(&zero)?;")]
1301        #[doc = concat!("let one = ", stringify!($inner), "::to_ne_bytes(1);")]
1302        #[doc = concat!("let one = buf::aligned_buf::<", stringify!($ty), ">(&one)?;")]
1303        ///
1304        /// let st = zero.load(Ref::<Struct>::zero())?;
1305        /// assert_eq!(st.field, None);
1306        ///
1307        /// let st = one.load(Ref::<Struct>::zero())?;
1308        #[doc = concat!("assert_eq!(st.field, ", stringify!($ty), "::new(1));")]
1309        /// # Ok::<_, musli_zerocopy::Error>(())
1310        /// ```
1311        unsafe impl ZeroCopy for Option<::core::num::$ty> {
1312            const ANY_BITS: bool = true;
1313            const PADDED: bool = false;
1314            const CAN_SWAP_BYTES: bool = true;
1315
1316            #[inline]
1317            unsafe fn pad(_: &mut Padder<'_, Self>) {}
1318
1319            #[inline]
1320            unsafe fn validate(_: &mut Validator<'_, Self>) -> Result<(), Error> {
1321                Ok(())
1322            }
1323
1324            #[inline]
1325            fn swap_bytes<E>(self) -> Self
1326            where
1327                E: ByteOrder,
1328            {
1329                // SAFETY: All bit-patterns are habitable, zero we can rely on
1330                // byte-order conversion from the inner type.
1331                unsafe {
1332                    transmute(<$inner as ZeroCopy>::swap_bytes::<E>(transmute::<
1333                        Self,
1334                        $inner,
1335                    >(self)))
1336                }
1337            }
1338        }
1339
1340        impl Visit for Option<::core::num::$ty> {
1341            type Target = Option<::core::num::$ty>;
1342
1343            #[inline]
1344            fn visit<V, O>(&self, _: &Buf, visitor: V) -> Result<O, Error>
1345            where
1346                V: FnOnce(&Self::Target) -> O,
1347            {
1348                Ok(visitor(self))
1349            }
1350        }
1351    };
1352}
1353
1354impl_nonzero_number!(NonZeroUsize, usize);
1355impl_nonzero_number!(NonZeroIsize, isize);
1356impl_nonzero_number!(NonZeroU8, u8);
1357impl_nonzero_number!(NonZeroU16, u16);
1358impl_nonzero_number!(NonZeroU32, u32);
1359impl_nonzero_number!(NonZeroU64, u64);
1360impl_nonzero_number!(NonZeroU128, u128);
1361impl_nonzero_number!(NonZeroI8, i8);
1362impl_nonzero_number!(NonZeroI16, i16);
1363impl_nonzero_number!(NonZeroI32, i32);
1364impl_nonzero_number!(NonZeroI64, i64);
1365impl_nonzero_number!(NonZeroI128, i128);
1366
1367macro_rules! impl_zst {
1368    ($({$($bounds:tt)*},)? $ty:ty, $expr:expr , {$example:ty $(, $import:path)?}) => {
1369        #[doc = concat!(" [`ZeroCopy`] implementation for `", stringify!($ty), "`")]
1370        ///
1371        /// # Examples
1372        ///
1373        /// ```
1374        $(#[doc = concat!("use ", stringify!($import), ";")])*
1375        /// use musli_zerocopy::{ZeroCopy, OwnedBuf};
1376        ///
1377        /// #[derive(Default, Clone, Copy, ZeroCopy)]
1378        /// #[repr(C)]
1379        /// struct Struct {
1380        #[doc = concat!("    field: ", stringify!($example), ",")]
1381        /// }
1382        ///
1383        /// let mut buf = OwnedBuf::new();
1384        /// let values = [Struct::default(); 100];
1385        /// let slice = buf.store_unsized(&values[..])?;
1386        /// buf.align_in_place()?;
1387        /// assert_eq!(buf.len(), 0);
1388        ///
1389        /// let slice = buf.load(slice)?;
1390        /// assert_eq!(slice.len(), 100);
1391        /// # Ok::<_, musli_zerocopy::Error>(())
1392        /// ```
1393        unsafe impl $(<$($bounds)*>)* ZeroCopy for $ty {
1394            const ANY_BITS: bool = true;
1395            const PADDED: bool = false;
1396            const CAN_SWAP_BYTES: bool = true;
1397
1398            #[inline]
1399            unsafe fn pad(_: &mut Padder<'_, Self>) {
1400            }
1401
1402            #[inline]
1403            unsafe fn validate(_: &mut Validator<'_, Self>) -> Result<(), Error> {
1404                Ok(())
1405            }
1406
1407            #[inline]
1408            fn swap_bytes<E>(self) -> Self
1409            where
1410                E: ByteOrder,
1411            {
1412                self
1413            }
1414        }
1415
1416        impl $(<$($bounds)*>)* Visit for $ty {
1417            type Target = $ty;
1418
1419            #[inline]
1420            fn visit<V, O>(&self, _: &Buf, visitor: V) -> Result<O, Error>
1421            where
1422                V: FnOnce(&Self::Target) -> O,
1423            {
1424                Ok(visitor(self))
1425            }
1426        }
1427    };
1428}
1429
1430impl_zst!((), (), { () });
1431impl_zst!({T}, PhantomData<T>, PhantomData, {PhantomData<u32>, std::marker::PhantomData});
1432
1433/// [`ZeroCopy`] implementation for `[T; 0]`.
1434///
1435/// # Examples
1436///
1437/// ```
1438/// use std::mem::align_of;
1439///
1440/// use musli_zerocopy::{ZeroCopy, OwnedBuf};
1441///
1442/// #[derive(Default, Clone, Copy, ZeroCopy)]
1443/// #[repr(C)]
1444/// struct Struct<T> {
1445///     #[zero_copy(ignore)]
1446///     field: [T; 0],
1447/// }
1448///
1449/// let mut buf = OwnedBuf::with_alignment::<u128>();
1450/// let values = [Struct::<u128>::default(); 100];
1451/// let slice = buf.store_unsized(&values[..])?;
1452/// buf.align_in_place()?;
1453/// assert_eq!(buf.len(), 0);
1454///
1455/// let slice = buf.load(slice)?;
1456/// assert_eq!(slice.len(), 100);
1457/// # Ok::<_, musli_zerocopy::Error>(())
1458/// ```
1459unsafe impl<T, const N: usize> ZeroCopy for [T; N]
1460where
1461    T: ZeroCopy,
1462{
1463    const ANY_BITS: bool = T::ANY_BITS;
1464    const PADDED: bool = T::PADDED;
1465    const CAN_SWAP_BYTES: bool = T::CAN_SWAP_BYTES;
1466
1467    #[inline]
1468    unsafe fn pad(padder: &mut Padder<'_, Self>) {
1469        for _ in 0..N {
1470            unsafe {
1471                padder.pad::<T>();
1472            }
1473        }
1474    }
1475
1476    #[inline]
1477    unsafe fn validate(validator: &mut Validator<'_, Self>) -> Result<(), Error> {
1478        for _ in 0..N {
1479            unsafe {
1480                validator.validate_only::<T>()?;
1481            }
1482        }
1483
1484        Ok(())
1485    }
1486
1487    #[inline]
1488    fn swap_bytes<E>(self) -> Self
1489    where
1490        E: ByteOrder,
1491    {
1492        let mut iter = self.into_iter();
1493        array::from_fn(move |_| T::swap_bytes::<E>(iter.next().unwrap()))
1494    }
1495}
1496
1497impl<T> Visit for [T; 0] {
1498    type Target = [T; 0];
1499
1500    #[inline]
1501    fn visit<V, O>(&self, _: &Buf, visitor: V) -> Result<O, Error>
1502    where
1503        V: FnOnce(&Self::Target) -> O,
1504    {
1505        Ok(visitor(self))
1506    }
1507}