Struct musli_zerocopy::pointer::Ref

source ·
#[repr(C)]
pub struct Ref<T, E: ByteOrder = Native, O: Size = DefaultSize>
where T: Pointee + ?Sized,
{ /* private fields */ }
Expand description

A stored reference to a type T.

A reference is made up of two components:

  • An offset() indicating the absolute offset into a Buf where the pointed-to (pointee) data is located.
  • An optional metadata() components, which if set indicates that this reference is a wide pointer. This is used when encoding types such as [T] or str to include additional data necessary to handle the type.

§Examples

use std::mem::align_of;

use musli_zerocopy::{Ref, OwnedBuf};

let mut buf = OwnedBuf::with_alignment::<u32>();
buf.extend_from_slice(&[1, 2, 3, 4]);

let buf = buf.as_ref();

let number = Ref::<u32>::new(0);
assert_eq!(*buf.load(number)?, u32::from_ne_bytes([1, 2, 3, 4]));

Implementations§

source§

impl<T, E: ByteOrder, O: Size> Ref<T, E, O>
where T: Pointee + ?Sized,

source

pub fn to_be(self) -> Ref<T, Big, O>

Convert this reference into a Big-endian ByteOrder.

§Examples
use musli_zerocopy::{endian, Ref};

let r: Ref<u32> = Ref::new(10);
assert_eq!(r.offset(), 10);

let r: Ref<u32, endian::Little> = Ref::new(10);
assert_eq!(r.offset(), 10);

let r: Ref<u32, endian::Big> = r.to_be();
assert_eq!(r.offset(), 10);
source

pub fn to_le(self) -> Ref<T, Little, O>

Convert this reference into a Little-endian ByteOrder.

§Examples
use musli_zerocopy::{endian, Ref};

let r: Ref<u32> = Ref::new(10);
assert_eq!(r.offset(), 10);

let r: Ref<u32, endian::Big> = Ref::new(10);
assert_eq!(r.offset(), 10);

let r: Ref<u32, endian::Little> = r.to_le();
assert_eq!(r.offset(), 10);
source

pub fn to_ne(self) -> Ref<T, Native, O>

Convert this reference into a Native-endian ByteOrder.

§Examples
use musli_zerocopy::{endian, Ref};

let r: Ref<u32, endian::Native> = Ref::<u32, endian::Big>::new(10).to_ne();
assert_eq!(r.offset(), 10);

let r: Ref<u32, endian::Native> = Ref::<u32, endian::Little>::new(10).to_ne();
assert_eq!(r.offset(), 10);

let r: Ref<u32, endian::Native> = Ref::<u32, endian::Native>::new(10).to_ne();
assert_eq!(r.offset(), 10);
source

pub fn to_endian<U: ByteOrder>(self) -> Ref<T, U, O>

Convert this reference into a U-endian ByteOrder.

§Examples
use musli_zerocopy::{endian, Ref};

let r: Ref<u32, endian::Native> = Ref::<u32, endian::Big>::new(10).to_endian();
assert_eq!(r.offset(), 10);

let r: Ref<u32, endian::Native> = Ref::<u32, endian::Little>::new(10).to_endian();
assert_eq!(r.offset(), 10);

let r: Ref<u32, endian::Native> = Ref::<u32, endian::Native>::new(10).to_endian();
assert_eq!(r.offset(), 10);
source§

impl<T, E: ByteOrder, O: Size> Ref<T, E, O>
where T: Pointee + ?Sized,

source

pub fn with_metadata<U>(offset: U, metadata: T::Metadata) -> Self
where U: Copy + Debug, O: TryFrom<U>,

Construct a reference with custom metadata.

§Panics

This will panic if either:

  • The offset or metadata can’t be byte swapped as per ZeroCopy::CAN_SWAP_BYTES.
  • Packed offset() cannot be constructed from U (out of range).
  • Packed metadata() cannot be constructed from T::Metadata (reason depends on the exact metadata).

To guarantee that this constructor will never panic, Ref<T, E, usize> can be used. This also ensures that construction is a no-op.

§Examples
use musli_zerocopy::Ref;

let reference = Ref::<[u64]>::with_metadata(42, 10);
assert_eq!(reference.offset(), 42);
assert_eq!(reference.len(), 10);
source

pub fn try_with_metadata<U>( offset: U, metadata: T::Metadata ) -> Result<Self, Error>
where U: Copy + IntoRepr + Debug, O: TryFrom<U>,

Fallibly try to construct a reference with metadata.

§Errors

This will error if either:

  • The offset or metadata can’t be byte swapped as per ZeroCopy::CAN_SWAP_BYTES.
  • Packed offset() cannot be constructed from U (out of range).
  • Packed metadata() cannot be constructed from T::Metadata (reason depends on the exact metadata).

To guarantee that this constructor will never error, Ref<T, Native, usize> can be used. This also ensures that construction is a no-op.

§Examples
use musli_zerocopy::Ref;

let reference = Ref::<[u64]>::try_with_metadata(42, 10)?;
assert_eq!(reference.offset(), 42);
assert_eq!(reference.len(), 10);
source§

impl<T, E: ByteOrder, O: Size> Ref<[T], E, O>
where T: ZeroCopy,

source

pub fn len(self) -> usize

Return the number of elements in the slice [T].

§Examples
use musli_zerocopy::pointer::Ref;

let slice = Ref::<[u32]>::with_metadata(0, 2);
assert_eq!(slice.len(), 2);
source

pub fn is_empty(self) -> bool

Test if the slice [T] is empty.

§Examples
use musli_zerocopy::pointer::Ref;

let slice = Ref::<[u32]>::with_metadata(0, 0);
assert!(slice.is_empty());

let slice = Ref::<[u32]>::with_metadata(0, 2);
assert!(!slice.is_empty());
source

pub fn get(self, index: usize) -> Option<Ref<T, E, O>>

Try to get a reference directly out of the slice without validation.

This avoids having to validate every element in a slice in order to address them.

§Examples
use musli_zerocopy::OwnedBuf;

let mut buf = OwnedBuf::new();
let slice = buf.store_slice(&[1, 2, 3, 4]);

let two = slice.get(2).expect("Missing element 2");
assert_eq!(buf.load(two)?, &3);

assert!(slice.get(4).is_none());
source

pub fn get_unchecked(self, index: usize) -> Ref<T, E, O>

Get an unchecked reference directly out of the slice without validation.

This avoids having to validate every element in a slice in order to address them.

In contrast to get(), this does not check that the index is within the bounds of the current slice, all though it’s not unsafe since it cannot lead to anything inherently unsafe. Only garbled data.

§Examples
use musli_zerocopy::OwnedBuf;

let mut buf = OwnedBuf::new();
let slice = buf.store_slice(&[1, 2, 3, 4]);

let two = slice.get_unchecked(2);
assert_eq!(buf.load(two)?, &3);

let oob = slice.get_unchecked(4);
assert!(buf.load(oob).is_err());
source

pub fn split_at(self, at: usize) -> (Self, Self)

Split the slice reference at the given position at.

§Panics

This panics if the given range is out of bounds.

§Examples
use musli_zerocopy::OwnedBuf;

let mut buf = OwnedBuf::new();
let slice = buf.store_slice(&[1, 2, 3, 4]);

buf.align_in_place();

let (a, b) = slice.split_at(3);
let (c, d) = slice.split_at(4);

assert_eq!(buf.load(a)?, &[1, 2, 3]);
assert_eq!(buf.load(b)?, &[4]);
assert_eq!(buf.load(c)?, &[1, 2, 3, 4]);
assert_eq!(buf.load(d)?, &[]);
source

pub fn iter(self) -> Iter<T, E, O>

Construct an iterator over this reference.

§Examples
use musli_zerocopy::OwnedBuf;

let mut buf = OwnedBuf::new();
buf.extend_from_slice(&[1, 2, 3, 4]);

let slice = buf.store_slice(&[1, 2, 3, 4]);

buf.align_in_place();

let mut out = Vec::new();

for r in slice.iter() {
    out.push(*buf.load(r)?);
}

for r in slice.iter().rev() {
    out.push(*buf.load(r)?);
}

assert_eq!(out, [1, 2, 3, 4, 4, 3, 2, 1]);
source§

impl<E: ByteOrder, O: Size> Ref<str, E, O>

source

pub fn len(self) -> usize

Return the length of the string.

§Examples
use musli_zerocopy::pointer::Ref;

let slice = Ref::<str>::with_metadata(0, 2);
assert_eq!(slice.len(), 2);
source

pub fn is_empty(self) -> bool

Test if the slice [T] is empty.

§Examples
use musli_zerocopy::pointer::Ref;

let slice = Ref::<str>::with_metadata(0, 0);
assert!(slice.is_empty());

let slice = Ref::<str>::with_metadata(0, 2);
assert!(!slice.is_empty());
source§

impl<T, E: ByteOrder, O: Size> Ref<T, E, O>
where T: Pointee + ?Sized,

source

pub fn metadata(self) -> <T::Metadata as Packable>::Packed<O>

The number of elements in the slice.

§Examples
use musli_zerocopy::pointer::Ref;

let slice = Ref::<str>::with_metadata(0, 10);
assert_eq!(slice.metadata(), 10);
source§

impl<T, E: ByteOrder, O: Size> Ref<T, E, O>
where T: Pointee<Metadata = ()>,

source

pub fn new<U>(offset: U) -> Self
where U: Copy + Debug, O: TryFrom<U>,

Construct a reference at the given offset.

§Panics

This will panic if either:

§Examples
use musli_zerocopy::Ref;

let reference = Ref::<u64>::new(42);
assert_eq!(reference.offset(), 42);
source

pub const fn zero() -> Self

Construct a typed reference to the zeroeth offset in a buffer.

§Examples
use musli_zerocopy::Ref;

let reference = Ref::<u64>::zero();
assert_eq!(reference.offset(), 0);
source§

impl<T, E: ByteOrder, O: Size> Ref<T, E, O>
where T: Pointee + ?Sized,

source

pub fn offset(self) -> usize

Get the offset the reference points to.

§Examples
use musli_zerocopy::Ref;

let reference = Ref::<u64>::new(42);
assert_eq!(reference.offset(), 42);
source

pub fn coerce<U>(self) -> Ref<U, E, O>
where T: Coerce<U>, U: Pointee + ?Sized,

Coerce from one kind of reference to another ensuring that the destination type U is size-compatible.

This performs metadata conversion if the destination metadata for U differs from T, such as for [u32] to [u8] it would multiply the length by 4 to ensure that the slice points to an appropriately sized region.

If the metadata conversion would overflow, this will wrap around the numerical bounds or panic for debug builds.

See try_coerce() for more documentation, which is also a checked variant of this method.

source

pub fn try_coerce<U>(self) -> Option<Ref<U, E, O>>
where T: Coerce<U>, U: Pointee + ?Sized,

Try to coerce from one kind of reference to another ensuring that the destination type U is size-compatible.

This performs metadata conversion if the destination metadata for U differs from T, such as for [u32] to [u8] it would multiply the length by 4 to ensure that the slice points to an appropriately sized region.

This returns None in case metadata would overflow due to the conversion.

use musli_zerocopy::Ref;

let reference: Ref<u64> = Ref::zero();
let reference2 = reference.coerce::<[u32]>();
assert_eq!(reference2.len(), 2);

This method ensures that coercions across inappropriate types are prohibited, such as coercing from a reference to a slice which is too large.

use musli_zerocopy::Ref;

let reference: Ref<u32> = Ref::zero();
let reference2 = reference.coerce::<[u64]>();

If metadata needs to be adjusted for the destination type such as for slices, it will be:

use musli_zerocopy::Ref;

let reference: Ref<[u32]> = Ref::with_metadata(0, 1);
let reference2 = reference.try_coerce::<[u8]>().ok_or("bad coercion")?;
assert_eq!(reference2.len(), 4);

let reference: Ref<str> = Ref::with_metadata(0, 12);
let reference2 = reference.try_coerce::<[u8]>().ok_or("bad coercion")?;
assert_eq!(reference2.len(), 12);

This does mean that numerical overflow might occur if the packed metadata is too small:

use musli_zerocopy::Ref;
use musli_zerocopy::endian::Native;

let reference = Ref::<[u32], Native, u8>::with_metadata(0, 64);
let reference2 = reference.try_coerce::<[u8]>();
assert!(reference2.is_none()); // 64 * 4 would overflow u8 packed metadata.

Coercion of non-zero types are supported, but do not guarantee that the destination data is valid.

source§

impl<T, const N: usize, E: ByteOrder, O: Size> Ref<[T; N], E, O>
where T: ZeroCopy,

source

pub fn array_into_slice(self) -> Ref<[T], E, O>

Coerce a reference to an array into a slice.

§Examples
use musli_zerocopy::OwnedBuf;

let mut buf = OwnedBuf::new();

let values = buf.store(&[1, 2, 3, 4]);
let slice = values.array_into_slice();

assert_eq!(buf.load(slice)?, &[1, 2, 3, 4]);
source§

impl<T, E: ByteOrder, O: Size> Ref<MaybeUninit<T>, E, O>
where T: Pointee,

source

pub const fn assume_init(self) -> Ref<T, E, O>

Assume that the reference is initialized.

Unlike the counterpart in Rust, this isn’t actually unsafe. Because in order to load the reference again we’d have to validate it anyways.

Trait Implementations§

source§

impl<T, E: ByteOrder, O: Size> Clone for Ref<T, E, O>
where T: Pointee + ?Sized,

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T, E: ByteOrder, O> Debug for Ref<T, E, O>
where T: Pointee + ?Sized, <T::Metadata as Packable>::Packed<O>: Debug, O: Debug + Size,

source§

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

Formats the value using the given formatter. Read more
source§

impl<T, E: ByteOrder, O> Hash for Ref<T, E, O>
where T: Pointee + ?Sized, O: Hash + Size, <T::Metadata as Packable>::Packed<O>: Hash,

source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<T, E: ByteOrder, O: Size> Load for Ref<[T], E, O>
where T: ZeroCopy,

§

type Target = [T]

The target being read.
source§

fn load<'buf>(&self, buf: &'buf Buf) -> Result<&'buf Self::Target, Error>

Validate the value.
source§

impl<T, E: ByteOrder, O: Size> Load for Ref<T, E, O>
where T: ZeroCopy,

§

type Target = T

The target being read.
source§

fn load<'buf>(&self, buf: &'buf Buf) -> Result<&'buf Self::Target, Error>

Validate the value.
source§

impl<E: ByteOrder, O: Size> Load for Ref<str, E, O>

§

type Target = str

The target being read.
source§

fn load<'buf>(&self, buf: &'buf Buf) -> Result<&'buf Self::Target, Error>

Validate the value.
source§

impl<T, E: ByteOrder, O: Size> LoadMut for Ref<[T], E, O>
where T: ZeroCopy,

source§

fn load_mut<'buf>( &self, buf: &'buf mut Buf ) -> Result<&'buf mut Self::Target, Error>

Validate the value.
source§

impl<T, E: ByteOrder, O: Size> LoadMut for Ref<T, E, O>
where T: ZeroCopy,

source§

fn load_mut<'buf>( &self, buf: &'buf mut Buf ) -> Result<&'buf mut Self::Target, Error>

Validate the value.
source§

impl<E: ByteOrder, O: Size> LoadMut for Ref<str, E, O>

source§

fn load_mut<'buf>( &self, buf: &'buf mut Buf ) -> Result<&'buf mut Self::Target, Error>

Validate the value.
source§

impl<T, E: ByteOrder, O> Ord for Ref<T, E, O>
where T: Pointee + ?Sized, O: Ord + Size, <T::Metadata as Packable>::Packed<O>: Ord,

source§

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

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl<T, E: ByteOrder, O> PartialEq for Ref<T, E, O>
where T: Pointee + ?Sized, O: PartialEq + Size, <T::Metadata as Packable>::Packed<O>: PartialEq,

source§

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

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<T, E: ByteOrder, O> PartialOrd for Ref<T, E, O>
where T: Pointee + ?Sized, O: Ord + Size, <T::Metadata as Packable>::Packed<O>: PartialOrd,

source§

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

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more
source§

impl<T, A: ByteOrder, B: Size> Slice for Ref<[T], A, B>
where T: ZeroCopy,

§

type Item = T

The item in an unsized slice, or the T in [T].
§

type ItemRef = Ref<T, A, B>

A returned reference to an item in a slice.
source§

fn from_ref<E: ByteOrder, O: Size>(slice: Ref<[T], E, O>) -> Self
where T: ZeroCopy,

Construct a slice from a [Ref<[Self::Item]>]. Read more
source§

fn try_from_ref<E: ByteOrder, O: Size>( slice: Ref<[T], E, O> ) -> Result<Self, Error>
where T: ZeroCopy,

Try to construct a slice from a [Ref<[Self::Item]>]. Read more
source§

fn with_metadata(offset: usize, len: usize) -> Self

Construct a slice from its offset and len. Read more
source§

fn try_with_metadata(offset: usize, len: usize) -> Result<Self, Error>

Construct a slice from its offset and len. Read more
source§

fn get(self, index: usize) -> Option<Self::ItemRef>

Try to get a reference directly out of the slice without validation. Read more
source§

fn split_at(self, at: usize) -> (Self, Self)

Split the slice at the given position at. Read more
source§

fn get_unchecked(self, index: usize) -> Self::ItemRef

Get an unchecked reference directly out of the slice without validation. Read more
source§

fn offset(self) -> usize

Get the offset the slice points to. Read more
source§

fn len(self) -> usize

Return the number of elements in the slice. Read more
source§

fn is_empty(self) -> bool

Test if the slice is empty. Read more
source§

impl<T, E: ByteOrder, O: Size> Visit for Ref<T, E, O>
where T: Pointee + ?Sized, Self: Load,

§

type Target = <Ref<T, E, O> as Load>::Target

The target type being visited.
source§

fn visit<V, U>(&self, buf: &Buf, visitor: V) -> Result<U, Error>
where V: FnOnce(&Self::Target) -> U,

Validate the value.
source§

impl<T, E: ByteOrder, O: Size> ZeroCopy for Ref<T, E, O>
where T: Pointee + ?Sized, <T::Metadata as Packable>::Packed<O>: ZeroCopy,

source§

const ANY_BITS: bool = _

Indicates if the type can inhabit all possible bit patterns within its size_of::<Self>() bytes.
source§

const PADDED: bool = _

Indicates if a type is padded.
source§

const CAN_SWAP_BYTES: bool = true

Indicates if the type has a valid byte-ordered transformation. Read more
source§

fn swap_bytes<__E: ByteOrder>(self) -> Self

Swap the bytes of self using the specified byte ordering to match the native byte ordering. Read more
source§

fn initialize_padding(&mut self)

Ensure that the padding for the current value is initialized. Read more
source§

fn to_bytes(&mut self) -> &[u8]

Convert a reference to a ZeroCopy type into bytes. Read more
source§

unsafe fn to_bytes_unchecked(&self) -> &[u8]

Convert a ZeroCopy type into bytes. Read more
source§

fn from_bytes(bytes: &[u8]) -> Result<&Self, Error>

Load bytes into a reference of Self. Read more
source§

fn from_bytes_mut(bytes: &mut [u8]) -> Result<&mut Self, Error>

Load bytes into a mutable reference of Self. Read more
source§

fn transpose_bytes<F: ByteOrder, T: ByteOrder>(self) -> Self

Transpose a type from one byte order F to another T.
source§

impl<T, E: ByteOrder, O: Size> Copy for Ref<T, E, O>
where T: Pointee + ?Sized,

source§

impl<T, E: ByteOrder, O> Eq for Ref<T, E, O>
where T: Pointee + ?Sized, O: Eq + Size, <T::Metadata as Packable>::Packed<O>: Eq,

Auto Trait Implementations§

§

impl<T, E, O> Freeze for Ref<T, E, O>
where O: Freeze, <<T as Pointee>::Metadata as Packable>::Packed<O>: Freeze, T: ?Sized,

§

impl<T, E, O> RefUnwindSafe for Ref<T, E, O>

§

impl<T, E, O> Send for Ref<T, E, O>
where O: Send, <<T as Pointee>::Metadata as Packable>::Packed<O>: Send, E: Send, T: Send + ?Sized,

§

impl<T, E, O> Sync for Ref<T, E, O>
where O: Sync, <<T as Pointee>::Metadata as Packable>::Packed<O>: Sync, E: Sync, T: Sync + ?Sized,

§

impl<T, E, O> Unpin for Ref<T, E, O>
where O: Unpin, <<T as Pointee>::Metadata as Packable>::Packed<O>: Unpin, E: Unpin, T: Unpin + ?Sized,

§

impl<T, E, O> UnwindSafe for Ref<T, E, O>

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

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

source§

fn into(self) -> U

Calls U::from(self).

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

source§

impl<T> Pointee for T
where T: ZeroCopy,

§

type Metadata = ()

Metadata associated with a pointee.
source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

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

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

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

Performs the conversion.