// SPDX-License-Identifier: (BSD-2-Clause OR Apache-2.0) OR MIT
// Copyright 2024 The Fuchsia Authors
//
// Licensed under the 2-Clause BSD License <LICENSE-BSD or
// https://opensource.org/license/bsd-2-clause>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
use super::*;
use crate::pointer::{
BecauseInvariantsEq, BecauseMutationCompatible, MutationCompatible, TransmuteFromPtr,
};
mod def {
use core::marker::PhantomData;
use crate::{
ByteSlice, ByteSliceMut, CloneableByteSlice, CopyableByteSlice, IntoByteSlice,
IntoByteSliceMut,
};
/// A typed reference derived from a byte slice.
///
/// A `Ref<B, T>` is a reference to a `T` which is stored in a byte slice, `B`.
/// Unlike a native reference (`&T` or `&mut T`), `Ref<B, T>` has the same
/// mutability as the byte slice it was constructed from (`B`).
///
/// # Examples
///
/// `Ref` can be used to treat a sequence of bytes as a structured type, and
/// to read and write the fields of that type as if the byte slice reference
/// were simply a reference to that type.
///
/// ```rust
/// use zerocopy::*;
/// # use zerocopy_derive::*;
///
/// #[derive(FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
/// #[repr(C)]
/// struct UdpHeader {
/// src_port: [u8; 2],
/// dst_port: [u8; 2],
/// length: [u8; 2],
/// checksum: [u8; 2],
/// }
///
/// #[derive(FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
/// #[repr(C, packed)]
/// struct UdpPacket {
/// header: UdpHeader,
/// body: [u8],
/// }
///
/// impl UdpPacket {
/// pub fn parse<B: ByteSlice>(bytes: B) -> Option<Ref<B, UdpPacket>> {
/// Ref::from_bytes(bytes).ok()
/// }
/// }
/// ```
pub struct Ref<B, T: ?Sized>(
// INVARIANTS: The referent (via `.deref`, `.deref_mut`, `.into`) byte
// slice is aligned to `T`'s alignment and its size corresponds to a
// valid size for `T`.
B,
PhantomData<T>,
);
impl<B, T: ?Sized> Ref<B, T> {
/// Constructs a new `Ref`.
///
/// # Safety
///
/// `bytes` dereferences (via [`deref`], [`deref_mut`], and [`into`]) to
/// a byte slice which is aligned to `T`'s alignment and whose size is a
/// valid size for `T`.
///
/// [`deref`]: core::ops::Deref::deref
/// [`deref_mut`]: core::ops::DerefMut::deref_mut
/// [`into`]: core::convert::Into::into
pub(crate) unsafe fn new_unchecked(bytes: B) -> Ref<B, T> {
// INVARIANTS: The caller has promised that `bytes`'s referent is