Trait SplitAt

Source
pub unsafe trait SplitAt: KnownLayout<PointerMetadata = usize> {
    type Elem;

    // Provided methods
    unsafe fn split_at_unchecked(&self, l_len: usize) -> (&Self, &[Self::Elem])
       where Self: Immutable { ... }
    fn split_at(&self, l_len: usize) -> Option<(&Self, &[Self::Elem])>
       where Self: Immutable { ... }
    unsafe fn split_at_mut_unchecked(
        &mut self,
        l_len: usize,
    ) -> (&mut Self, &mut [Self::Elem]) { ... }
    fn split_at_mut(
        &mut self,
        l_len: usize,
    ) -> Option<(&mut Self, &mut [Self::Elem])> { ... }
}
Expand description

Types that can be split in two.

§Implementation

Do not implement this trait yourself! Instead, use #[derive(SplitAt)]; e.g.:

#[derive(SplitAt, KnownLayout)]
#[repr(C)]
struct MyStruct<T: ?Sized> {
    ...,
    // `SplitAt` types must have at least one field.
    field: T,
}

This derive performs a sophisticated, compile-time safety analysis to determine whether a type is SplitAt.

§Safety

This trait does not convey any safety guarantees to code outside this crate.

You must not rely on the #[doc(hidden)] internals of SplitAt. Future releases of zerocopy may make backwards-breaking changes to these items, including changes that only affect soundness, which may cause code which uses those items to silently become unsound.

Required Associated Types§

Source

type Elem

The element type of the trailing slice.

Provided Methods§

Source

unsafe fn split_at_unchecked(&self, l_len: usize) -> (&Self, &[Self::Elem])
where Self: Immutable,

Unsafely splits self in two.

§Safety

The caller promises that l_len is not greater than the length of self’s trailing slice.

Source

fn split_at(&self, l_len: usize) -> Option<(&Self, &[Self::Elem])>
where Self: Immutable,

Attempts to split self in two.

Returns None if l_len is greater than the length of self’s trailing slice.

§Examples
use zerocopy::{SplitAt, FromBytes};

#[derive(SplitAt, FromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct Packet {
    length: u8,
    body: [u8],
}

// These bytes encode a `Packet`.
let bytes = &[4, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];

let packet = Packet::ref_from_bytes(bytes).unwrap();

assert_eq!(packet.length, 4);
assert_eq!(packet.body, [1, 2, 3, 4, 5, 6, 7, 8, 9]);

let (packet, rest) = packet.split_at(packet.length as usize).unwrap();
assert_eq!(packet.length, 4);
assert_eq!(packet.body, [1, 2, 3, 4]);
assert_eq!(rest, [5, 6, 7, 8, 9]);
Source

unsafe fn split_at_mut_unchecked( &mut self, l_len: usize, ) -> (&mut Self, &mut [Self::Elem])

Unsafely splits self in two.

§Safety

The caller promises that: 0. l_len is not greater than the length of self’s trailing slice.

  1. The trailing padding bytes of the left portion will not overlap the right portion. For some dynamically sized types, the padding that appears after the trailing slice field is a dynamic function of the trailing slice length. Thus, for some types, this condition is dependent on the value of l_len.
Source

fn split_at_mut( &mut self, l_len: usize, ) -> Option<(&mut Self, &mut [Self::Elem])>

Attempts to split self in two.

Returns None if l_len is greater than the length of self’s trailing slice, or if the given l_len would result in the trailing padding of the left portion overlapping the right portion.

§Examples
use zerocopy::{SplitAt, FromBytes};

#[derive(SplitAt, FromBytes, KnownLayout, Immutable, IntoBytes)]
#[repr(C)]
struct Packet<B: ?Sized> {
    length: u8,
    body: B,
}

// These bytes encode a `Packet`.
let mut bytes = &mut [4, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];

let packet = Packet::<[u8]>::mut_from_bytes(bytes).unwrap();

assert_eq!(packet.length, 4);
assert_eq!(packet.body, [1, 2, 3, 4, 5, 6, 7, 8, 9]);

{
    let (packet, rest) = packet.split_at_mut(packet.length as usize).unwrap();
    assert_eq!(packet.length, 4);
    assert_eq!(packet.body, [1, 2, 3, 4]);
    assert_eq!(rest, [5, 6, 7, 8, 9]);

    rest.fill(0);
}

assert_eq!(packet.length, 4);
assert_eq!(packet.body, [1, 2, 3, 4, 0, 0, 0, 0, 0]);

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl<T> SplitAt for [T]

Source§

type Elem = T

Implementors§