Struct Ref

pub struct Ref<B, T: ?Sized>(/* private field */, /* private field */);

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.

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()
    }
}

Implementations

impl<'a, B, T> Ref<B, T> where B: 'a + IntoByteSlice<'a>, T: FromBytes + KnownLayout + Immutable + ?Sized,

fn into_ref(r: Self) -> &'a T

Converts this Ref into a reference.

into_ref consumes the Ref, and returns a reference to T.

Note: this is an associated function, which means that you have to call it as Ref::into_ref(r) instead of r.into_ref(). This is so that there is no conflict with a method on the inner type.

impl<'a, B, T> Ref<B, T> where B: 'a + IntoByteSliceMut<'a>, T: FromBytes + IntoBytes + KnownLayout + ?Sized,

fn into_mut(r: Self) -> &'a mut T

Converts this Ref into a mutable reference.

into_mut consumes the Ref, and returns a mutable reference to T.

Note: this is an associated function, which means that you have to call it as Ref::into_mut(r) instead of r.into_mut(). This is so that there is no conflict with a method on the inner type.

impl<B, T> Ref<B, T> where B: ByteSlice, T: ?Sized,

fn bytes(r: &Self) -> &[u8]

Gets the underlying bytes.

Note: this is an associated function, which means that you have to call it as Ref::bytes(r) instead of r.bytes(). This is so that there is no conflict with a method on the inner type.

impl<B, T> Ref<B, T> where B: ByteSlice, T: FromBytes,

fn read(r: &Self) -> T

Reads a copy of T.

Note: this is an associated function, which means that you have to call it as Ref::read(r) instead of r.read(). This is so that there is no conflict with a method on the inner type.

impl<B, T> Ref<B, T> where B: ByteSlice, T: KnownLayout + Immutable + ?Sized,

fn from_bytes(source: B) -> Result<Ref<B, T>, CastError<B, T>>

Constructs a Ref from a byte slice.

If the length of source is not a valid size of T, or if source is not appropriately aligned for T, this returns Err. If T: Unaligned, you can infallibly discard the alignment error.

T may be a sized type, a slice, or a slice DST.

Compile-Time Assertions

This method cannot yet be used on unsized types whose dynamically-sized component is zero-sized. Attempting to use this method on such types results in a compile-time assertion error; e.g.:

use zerocopy::*;
# use zerocopy_derive::*;

#[derive(Immutable, KnownLayout)]
#[repr(C)]
struct ZSTy {
    leading_sized: u16,
    trailing_dst: [()],
}

let _ = Ref::<_, ZSTy>::from_bytes(&b"UU"[..]); // ⚠ Compile Error!

impl<B, T> Ref<B, T> where B: ByteSlice, T: KnownLayout<PointerMetadata = usize> + Immutable + ?Sized,

fn from_bytes_with_elems(source: B, count: usize) -> Result<Ref<B, T>, CastError<B, T>>

Constructs a Ref from the given bytes with DST length equal to count without copying.

This method attempts to return a Ref to the prefix of source interpreted as a T with count trailing elements, and a reference to the remaining bytes. If the length of source is not equal to the size of Self with count elements, or if source is not appropriately aligned, this returns Err. If T: Unaligned, you can infallibly discard the alignment error.

Compile-Time Assertions

This method cannot yet be used on unsized types whose dynamically-sized component is zero-sized. Attempting to use this method on such types results in a compile-time assertion error; e.g.:

use zerocopy::*;
# use zerocopy_derive::*;

#[derive(Immutable, KnownLayout)]
#[repr(C)]
struct ZSTy {
    leading_sized: u16,
    trailing_dst: [()],
}

let _ = Ref::<_, ZSTy>::from_bytes_with_elems(&b"UU"[..], 42); // ⚠ Compile Error!

impl<B, T> Ref<B, T> where B: ByteSliceMut, T: ?Sized,

fn bytes_mut(r: &mut Self) -> &mut [u8]

Gets the underlying bytes mutably.

Note: this is an associated function, which means that you have to call it as Ref::bytes_mut(r) instead of r.bytes_mut(). This is so that there is no conflict with a method on the inner type.

impl<B, T> Ref<B, T> where B: ByteSliceMut, T: IntoBytes,

fn write(r: &mut Self, t: T)

Writes the bytes of t and then forgets t.

Note: this is an associated function, which means that you have to call it as Ref::write(r, t) instead of r.write(t). This is so that there is no conflict with a method on the inner type.

impl<B, T> Ref<B, T> where B: SplitByteSlice, T: KnownLayout + Immutable + ?Sized,

fn from_prefix(source: B) -> Result<(Ref<B, T>, B), CastError<B, T>>

Constructs a Ref from the prefix of a byte slice.

This method computes the largest possible size of T that can fit in the leading bytes of source, then attempts to return both a Ref to those bytes, and a reference to the remaining bytes. If there are insufficient bytes, or if source is not appropriately aligned, this returns Err. If T: Unaligned, you can infallibly discard the alignment error.

T may be a sized type, a slice, or a slice DST.

Compile-Time Assertions

This method cannot yet be used on unsized types whose dynamically-sized component is zero-sized. Attempting to use this method on such types results in a compile-time assertion error; e.g.:

use zerocopy::*;
# use zerocopy_derive::*;

#[derive(Immutable, KnownLayout)]
#[repr(C)]
struct ZSTy {
    leading_sized: u16,
    trailing_dst: [()],
}

let _ = Ref::<_, ZSTy>::from_prefix(&b"UU"[..]); // ⚠ Compile Error!
fn from_suffix(source: B) -> Result<(B, Ref<B, T>), CastError<B, T>>

Constructs a Ref from the suffix of a byte slice.

This method computes the largest possible size of T that can fit in the trailing bytes of source, then attempts to return both a Ref to those bytes, and a reference to the preceding bytes. If there are insufficient bytes, or if that suffix of source is not appropriately aligned, this returns Err. If T: Unaligned, you can infallibly discard the alignment error.

T may be a sized type, a slice, or a slice DST.

Compile-Time Assertions

This method cannot yet be used on unsized types whose dynamically-sized component is zero-sized. Attempting to use this method on such types results in a compile-time assertion error; e.g.:

use zerocopy::*;
# use zerocopy_derive::*;

#[derive(Immutable, KnownLayout)]
#[repr(C)]
struct ZSTy {
    leading_sized: u16,
    trailing_dst: [()],
}

let _ = Ref::<_, ZSTy>::from_suffix(&b"UU"[..]); // ⚠ Compile Error!

impl<B, T> Ref<B, T> where B: SplitByteSlice, T: KnownLayout<PointerMetadata = usize> + Immutable + ?Sized,

fn from_prefix_with_elems(source: B, count: usize) -> Result<(Ref<B, T>, B), CastError<B, T>>

Constructs a Ref from the prefix of the given bytes with DST length equal to count without copying.

This method attempts to return a Ref to the prefix of source interpreted as a T with count trailing elements, and a reference to the remaining bytes. If there are insufficient bytes, or if source is not appropriately aligned, this returns Err. If T: Unaligned, you can infallibly discard the alignment error.

Compile-Time Assertions

This method cannot yet be used on unsized types whose dynamically-sized component is zero-sized. Attempting to use this method on such types results in a compile-time assertion error; e.g.:

use zerocopy::*;
# use zerocopy_derive::*;

#[derive(Immutable, KnownLayout)]
#[repr(C)]
struct ZSTy {
    leading_sized: u16,
    trailing_dst: [()],
}

let _ = Ref::<_, ZSTy>::from_prefix_with_elems(&b"UU"[..], 42); // ⚠ Compile Error!
fn from_suffix_with_elems(source: B, count: usize) -> Result<(B, Ref<B, T>), CastError<B, T>>

Constructs a Ref from the suffix of the given bytes with DST length equal to count without copying.

This method attempts to return a Ref to the suffix of source interpreted as a T with count trailing elements, and a reference to the preceding bytes. If there are insufficient bytes, or if that suffix of source is not appropriately aligned, this returns Err. If T: Unaligned, you can infallibly discard the alignment error.

Compile-Time Assertions

This method cannot yet be used on unsized types whose dynamically-sized component is zero-sized. Attempting to use this method on such types results in a compile-time assertion error; e.g.:

use zerocopy::*;
# use zerocopy_derive::*;

#[derive(Immutable, KnownLayout)]
#[repr(C)]
struct ZSTy {
    leading_sized: u16,
    trailing_dst: [()],
}

let _ = Ref::<_, ZSTy>::from_suffix_with_elems(&b"UU"[..], 42); // ⚠ Compile Error!

Trait Implementations

impl<B, T> Deref for Ref<B, T> where B: ByteSlice, T: FromBytes + KnownLayout + Immutable + ?Sized,

type Target = T;
fn deref(&self) -> &T

impl<B, T> DerefMut for Ref<B, T> where B: ByteSliceMut, T: FromBytes + IntoBytes + KnownLayout + Immutable + ?Sized,

fn deref_mut(&mut self) -> &mut T

impl<B: CloneableByteSlice + Clone, T: ?Sized> Clone for Ref<B, T>

fn clone(&self) -> Ref<B, T>

impl<B: CopyableByteSlice + Copy, T: ?Sized> Copy for Ref<B, T>

impl<T, B> Debug for Ref<B, T> where B: ByteSlice, T: FromBytes + Debug + KnownLayout + Immutable + ?Sized,

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result

impl<T, B> Display for Ref<B, T> where B: ByteSlice, T: FromBytes + Display + KnownLayout + Immutable + ?Sized,

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result

impl<T, B> Eq for Ref<B, T> where B: ByteSlice, T: FromBytes + Eq + KnownLayout + Immutable + ?Sized,

impl<T, B> Ord for Ref<B, T> where B: ByteSlice, T: FromBytes + Ord + KnownLayout + Immutable + ?Sized,

fn cmp(&self, other: &Self) -> Ordering

impl<T, B> PartialEq for Ref<B, T> where B: ByteSlice, T: FromBytes + PartialEq + KnownLayout + Immutable + ?Sized,

fn eq(&self, other: &Self) -> bool

impl<T, B> PartialOrd for Ref<B, T> where B: ByteSlice, T: FromBytes + PartialOrd + KnownLayout + Immutable + ?Sized,

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

Auto Trait Implementations

impl<B, T> Freeze for Ref<B, T> where B: Freeze, PhantomData<T>: Freeze, T: ?Sized,

impl<B, T> RefUnwindSafe for Ref<B, T> where B: RefUnwindSafe, PhantomData<T>: RefUnwindSafe, T: ?Sized,

impl<B, T> Send for Ref<B, T> where B: Send, PhantomData<T>: Send, T: ?Sized,

impl<B, T> Sync for Ref<B, T> where B: Sync, PhantomData<T>: Sync, T: ?Sized,

impl<B, T> Unpin for Ref<B, T> where B: Unpin, PhantomData<T>: Unpin, T: ?Sized,

impl<B, T> UnsafeUnpin for Ref<B, T> where B: UnsafeUnpin, PhantomData<T>: UnsafeUnpin, T: ?Sized,

impl<B, T> UnwindSafe for Ref<B, T> where B: UnwindSafe, PhantomData<T>: UnwindSafe, T: ?Sized,

Blanket Implementations

impl<P, T> Receiver for Ref<B, T> where P: Deref<Target = T> + ?Sized, T: ?Sized,

type Target = T;

impl<T> Any for Ref<B, T> where T: 'static + ?Sized,

fn type_id(&self) -> TypeId

impl<T> Borrow<T> for Ref<B, T> where T: ?Sized,

fn borrow(&self) -> &T

impl<T> BorrowMut<T> for Ref<B, T> where T: ?Sized,

fn borrow_mut(&mut self) -> &mut T

impl<T> CloneToUninit for Ref<B, T> where T: Clone,

unsafe fn clone_to_uninit(&self, dest: *mut u8)

impl<T> From<T> for Ref<B, T>

fn from(t: T) -> T

Returns the argument unchanged.

impl<T, U> Into<U> for Ref<B, T> where U: From<T>,

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom<U> for Ref<B, T> where U: Into<T>,

type Error = never;
fn try_from(value: U) -> Result<T, never>

impl<T, U> TryInto<U> for Ref<B, T> where U: TryFrom<T>,

type Error = <U as TryFrom<T>>::Error;
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>