zerocopy

Trait TryFromBytes

Source
pub unsafe trait TryFromBytes {
Show 15 methods // Provided methods fn try_ref_from_bytes( source: &[u8], ) -> Result<&Self, TryCastError<&[u8], Self>> where Self: KnownLayout + Immutable { ... } fn try_ref_from_prefix( source: &[u8], ) -> Result<(&Self, &[u8]), TryCastError<&[u8], Self>> where Self: KnownLayout + Immutable { ... } fn try_ref_from_suffix( source: &[u8], ) -> Result<(&[u8], &Self), TryCastError<&[u8], Self>> where Self: KnownLayout + Immutable { ... } fn try_mut_from_bytes( bytes: &mut [u8], ) -> Result<&mut Self, TryCastError<&mut [u8], Self>> where Self: KnownLayout { ... } fn try_mut_from_prefix( source: &mut [u8], ) -> Result<(&mut Self, &mut [u8]), TryCastError<&mut [u8], Self>> where Self: KnownLayout { ... } fn try_mut_from_suffix( source: &mut [u8], ) -> Result<(&mut [u8], &mut Self), TryCastError<&mut [u8], Self>> where Self: KnownLayout { ... } fn try_ref_from_bytes_with_elems( source: &[u8], count: usize, ) -> Result<&Self, TryCastError<&[u8], Self>> where Self: KnownLayout<PointerMetadata = usize> + Immutable { ... } fn try_ref_from_prefix_with_elems( source: &[u8], count: usize, ) -> Result<(&Self, &[u8]), TryCastError<&[u8], Self>> where Self: KnownLayout<PointerMetadata = usize> + Immutable { ... } fn try_ref_from_suffix_with_elems( source: &[u8], count: usize, ) -> Result<(&[u8], &Self), TryCastError<&[u8], Self>> where Self: KnownLayout<PointerMetadata = usize> + Immutable { ... } fn try_mut_from_bytes_with_elems( source: &mut [u8], count: usize, ) -> Result<&mut Self, TryCastError<&mut [u8], Self>> where Self: KnownLayout<PointerMetadata = usize> { ... } fn try_mut_from_prefix_with_elems( source: &mut [u8], count: usize, ) -> Result<(&mut Self, &mut [u8]), TryCastError<&mut [u8], Self>> where Self: KnownLayout<PointerMetadata = usize> { ... } fn try_mut_from_suffix_with_elems( source: &mut [u8], count: usize, ) -> Result<(&mut [u8], &mut Self), TryCastError<&mut [u8], Self>> where Self: KnownLayout<PointerMetadata = usize> { ... } fn try_read_from_bytes( source: &[u8], ) -> Result<Self, TryReadError<&[u8], Self>> where Self: Sized { ... } fn try_read_from_prefix( source: &[u8], ) -> Result<(Self, &[u8]), TryReadError<&[u8], Self>> where Self: Sized { ... } fn try_read_from_suffix( source: &[u8], ) -> Result<(&[u8], Self), TryReadError<&[u8], Self>> where Self: Sized { ... }
}
Expand description

Types for which some bit patterns are valid.

A memory region of the appropriate length which contains initialized bytes can be viewed as a TryFromBytes type so long as the runtime value of those bytes corresponds to a valid instance of that type. For example, bool is TryFromBytes, so zerocopy can transmute a u8 into a bool so long as it first checks that the value of the u8 is 0 or 1.

§Implementation

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

#[derive(TryFromBytes)]
struct MyStruct {
    ...
}

#[derive(TryFromBytes)]
#[repr(u8)]
enum MyEnum {
    ...
}

#[derive(TryFromBytes, Immutable)]
union MyUnion {
    ...
}

This derive ensures that the runtime check of whether bytes correspond to a valid instance is sound. You must implement this trait via the derive.

§What is a “valid instance”?

In Rust, each type has bit validity, which refers to the set of bit patterns which may appear in an instance of that type. It is impossible for safe Rust code to produce values which violate bit validity (ie, values outside of the “valid” set of bit patterns). If unsafe code produces an invalid value, this is considered undefined behavior.

Rust’s bit validity rules are currently being decided, which means that some types have three classes of bit patterns: those which are definitely valid, and whose validity is documented in the language; those which may or may not be considered valid at some point in the future; and those which are definitely invalid.

Zerocopy takes a conservative approach, and only considers a bit pattern to be valid if its validity is a documenteed guarantee provided by the language.

For most use cases, Rust’s current guarantees align with programmers’ intuitions about what ought to be valid. As a result, zerocopy’s conservatism should not affect most users.

If you are negatively affected by lack of support for a particular type, we encourage you to let us know by filing an issue.

§TryFromBytes is not symmetrical with IntoBytes

There are some types which implement both TryFromBytes and IntoBytes, but for which TryFromBytes is not guaranteed to accept all byte sequences produced by IntoBytes. In other words, for some T: TryFromBytes + IntoBytes, there exist values of t: T such that TryFromBytes::try_ref_from_bytes(t.as_bytes()) == None. Code should not generally assume that values produced by IntoBytes will necessarily be accepted as valid by TryFromBytes.

§Safety

On its own, T: TryFromBytes does not make any guarantees about the layout or representation of T. It merely provides the ability to perform a validity check at runtime via methods like try_ref_from_bytes.

You must not rely on the #[doc(hidden)] internals of TryFromBytes. 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.

Provided Methods§

Source

fn try_ref_from_bytes(source: &[u8]) -> Result<&Self, TryCastError<&[u8], Self>>
where Self: KnownLayout + Immutable,

Attempts to interpret the given source as a &Self.

If the bytes of source are a valid instance of Self, this method returns a reference to those bytes interpreted as a Self. If the length of source is not a valid size of Self, or if source is not appropriately aligned, or if source is not a valid instance of Self, this returns Err. If Self: Unaligned, you can infallibly discard the alignment error.

Self 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::*;

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

let _ = ZSTy::try_ref_from_bytes(0u16.as_bytes()); // ⚠ Compile Error!
§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the byte sequence `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
    marshmallows: [[u8; 2]],
}

let bytes = &[0xC0, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5][..];

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

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);
assert_eq!(packet.marshmallows, [[0, 1], [2, 3], [4, 5]]);

// These bytes are not valid instance of `Packet`.
let bytes = &[0x10, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5][..];
assert!(Packet::try_ref_from_bytes(bytes).is_err());
Source

fn try_ref_from_prefix( source: &[u8], ) -> Result<(&Self, &[u8]), TryCastError<&[u8], Self>>
where Self: KnownLayout + Immutable,

Attempts to interpret the prefix of the given source as a &Self.

This method computes the largest possible size of Self that can fit in the leading bytes of source. If that prefix is a valid instance of Self, this method returns a reference to those bytes interpreted as Self, and a reference to the remaining bytes. If there are insufficient bytes, or if source is not appropriately aligned, or if those bytes are not a valid instance of Self, this returns Err. If Self: Unaligned, you can infallibly discard the alignment error.

Self 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::*;

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

let _ = ZSTy::try_ref_from_prefix(0u16.as_bytes()); // ⚠ Compile Error!
§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
    marshmallows: [[u8; 2]],
}

// These are more bytes than are needed to encode a `Packet`.
let bytes = &[0xC0, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5, 6][..];

let (packet, suffix) = Packet::try_ref_from_prefix(bytes).unwrap();

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);
assert_eq!(packet.marshmallows, [[0, 1], [2, 3], [4, 5]]);
assert_eq!(suffix, &[6u8][..]);

// These bytes are not valid instance of `Packet`.
let bytes = &[0x10, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5, 6][..];
assert!(Packet::try_ref_from_prefix(bytes).is_err());
Source

fn try_ref_from_suffix( source: &[u8], ) -> Result<(&[u8], &Self), TryCastError<&[u8], Self>>
where Self: KnownLayout + Immutable,

Attempts to interpret the suffix of the given source as a &Self.

This method computes the largest possible size of Self that can fit in the trailing bytes of source. If that suffix is a valid instance of Self, this method returns a reference to those bytes interpreted as Self, and a reference to the preceding bytes. If there are insufficient bytes, or if the suffix of source would not be appropriately aligned, or if the suffix is not a valid instance of Self, this returns Err. If Self: Unaligned, you can infallibly discard the alignment error.

Self 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::*;

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

let _ = ZSTy::try_ref_from_suffix(0u16.as_bytes()); // ⚠ Compile Error!
§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
    marshmallows: [[u8; 2]],
}

// These are more bytes than are needed to encode a `Packet`.
let bytes = &[0, 0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7][..];

let (prefix, packet) = Packet::try_ref_from_suffix(bytes).unwrap();

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);
assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
assert_eq!(prefix, &[0u8][..]);

// These bytes are not valid instance of `Packet`.
let bytes = &[0, 1, 2, 3, 4, 5, 6, 77, 240, 0xC0, 0x10][..];
assert!(Packet::try_ref_from_suffix(bytes).is_err());
Source

fn try_mut_from_bytes( bytes: &mut [u8], ) -> Result<&mut Self, TryCastError<&mut [u8], Self>>
where Self: KnownLayout,

Attempts to interpret the given source as a &mut Self without copying.

If the bytes of source are a valid instance of Self, this method returns a reference to those bytes interpreted as a Self. If the length of source is not a valid size of Self, or if source is not appropriately aligned, or if source is not a valid instance of Self, this returns Err. If Self: Unaligned, you can infallibly discard the alignment error.

Self 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::*;

#[derive(TryFromBytes, KnownLayout)]
#[repr(C)]
struct ZSTy {
    leading_sized: [u8; 2],
    trailing_dst: [()],
}

let mut source = [85, 85];
let _ = ZSTy::try_mut_from_bytes(&mut source[..]); // ⚠ Compile Error!
§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes, KnownLayout)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes, KnownLayout)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
    marshmallows: [[u8; 2]],
}

let bytes = &mut [0xC0, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5][..];

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

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);
assert_eq!(packet.marshmallows, [[0, 1], [2, 3], [4, 5]]);

packet.temperature = 111;

assert_eq!(bytes, [0xC0, 0xC0, 240, 111, 0, 1, 2, 3, 4, 5]);

// These bytes are not valid instance of `Packet`.
let bytes = &mut [0x10, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5, 6][..];
assert!(Packet::try_mut_from_bytes(bytes).is_err());
Source

fn try_mut_from_prefix( source: &mut [u8], ) -> Result<(&mut Self, &mut [u8]), TryCastError<&mut [u8], Self>>
where Self: KnownLayout,

Attempts to interpret the prefix of the given source as a &mut Self.

This method computes the largest possible size of Self that can fit in the leading bytes of source. If that prefix is a valid instance of Self, this method returns a reference to those bytes interpreted as Self, and a reference to the remaining bytes. If there are insufficient bytes, or if source is not appropriately aligned, or if the bytes are not a valid instance of Self, this returns Err. If Self: Unaligned, you can infallibly discard the alignment error.

Self 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::*;

#[derive(TryFromBytes, KnownLayout)]
#[repr(C)]
struct ZSTy {
    leading_sized: [u8; 2],
    trailing_dst: [()],
}

let mut source = [85, 85];
let _ = ZSTy::try_mut_from_prefix(&mut source[..]); // ⚠ Compile Error!
§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes, KnownLayout)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes, KnownLayout)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
    marshmallows: [[u8; 2]],
}

// These are more bytes than are needed to encode a `Packet`.
let bytes = &mut [0xC0, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5, 6][..];

let (packet, suffix) = Packet::try_mut_from_prefix(bytes).unwrap();

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);
assert_eq!(packet.marshmallows, [[0, 1], [2, 3], [4, 5]]);
assert_eq!(suffix, &[6u8][..]);

packet.temperature = 111;
suffix[0] = 222;

assert_eq!(bytes, [0xC0, 0xC0, 240, 111, 0, 1, 2, 3, 4, 5, 222]);

// These bytes are not valid instance of `Packet`.
let bytes = &mut [0x10, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5, 6][..];
assert!(Packet::try_mut_from_prefix(bytes).is_err());
Source

fn try_mut_from_suffix( source: &mut [u8], ) -> Result<(&mut [u8], &mut Self), TryCastError<&mut [u8], Self>>
where Self: KnownLayout,

Attempts to interpret the suffix of the given source as a &mut Self.

This method computes the largest possible size of Self that can fit in the trailing bytes of source. If that suffix is a valid instance of Self, this method returns a reference to those bytes interpreted as Self, and a reference to the preceding bytes. If there are insufficient bytes, or if the suffix of source would not be appropriately aligned, or if the suffix is not a valid instance of Self, this returns Err. If Self: Unaligned, you can infallibly discard the alignment error.

Self 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::*;

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

let mut source = [85, 85];
let _ = ZSTy::try_mut_from_suffix(&mut source[..]); // ⚠ Compile Error!
§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes, KnownLayout)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes, KnownLayout)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
    marshmallows: [[u8; 2]],
}

// These are more bytes than are needed to encode a `Packet`.
let bytes = &mut [0, 0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7][..];

let (prefix, packet) = Packet::try_mut_from_suffix(bytes).unwrap();

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);
assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
assert_eq!(prefix, &[0u8][..]);

prefix[0] = 111;
packet.temperature = 222;

assert_eq!(bytes, [111, 0xC0, 0xC0, 240, 222, 2, 3, 4, 5, 6, 7]);

// These bytes are not valid instance of `Packet`.
let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 77, 240, 0xC0, 0x10][..];
assert!(Packet::try_mut_from_suffix(bytes).is_err());
Source

fn try_ref_from_bytes_with_elems( source: &[u8], count: usize, ) -> Result<&Self, TryCastError<&[u8], Self>>
where Self: KnownLayout<PointerMetadata = usize> + Immutable,

Attempts to interpret the given source as a &Self with a DST length equal to count.

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

§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
    marshmallows: [[u8; 2]],
}

let bytes = &[0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7][..];

let packet = Packet::try_ref_from_bytes_with_elems(bytes, 3).unwrap();

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);
assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);

// These bytes are not valid instance of `Packet`.
let bytes = &[0, 1, 2, 3, 4, 5, 6, 77, 240, 0xC0, 0xC0][..];
assert!(Packet::try_ref_from_bytes_with_elems(bytes, 3).is_err());

Since an explicit count is provided, this method supports types with zero-sized trailing slice elements. Methods such as try_ref_from_bytes which do not take an explicit count do not support such types.

use core::num::NonZeroU16;
use zerocopy::*;

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

let src = 0xCAFEu16.as_bytes();
let zsty = ZSTy::try_ref_from_bytes_with_elems(src, 42).unwrap();
assert_eq!(zsty.trailing_dst.len(), 42);
Source

fn try_ref_from_prefix_with_elems( source: &[u8], count: usize, ) -> Result<(&Self, &[u8]), TryCastError<&[u8], Self>>
where Self: KnownLayout<PointerMetadata = usize> + Immutable,

Attempts to interpret the prefix of the given source as a &Self with a DST length equal to count.

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

§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
    marshmallows: [[u8; 2]],
}

let bytes = &[0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7, 8][..];

let (packet, suffix) = Packet::try_ref_from_prefix_with_elems(bytes, 3).unwrap();

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);
assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
assert_eq!(suffix, &[8u8][..]);

// These bytes are not valid instance of `Packet`.
let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 77, 240, 0xC0, 0xC0][..];
assert!(Packet::try_ref_from_prefix_with_elems(bytes, 3).is_err());

Since an explicit count is provided, this method supports types with zero-sized trailing slice elements. Methods such as try_ref_from_prefix which do not take an explicit count do not support such types.

use core::num::NonZeroU16;
use zerocopy::*;

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

let src = 0xCAFEu16.as_bytes();
let (zsty, _) = ZSTy::try_ref_from_prefix_with_elems(src, 42).unwrap();
assert_eq!(zsty.trailing_dst.len(), 42);
Source

fn try_ref_from_suffix_with_elems( source: &[u8], count: usize, ) -> Result<(&[u8], &Self), TryCastError<&[u8], Self>>
where Self: KnownLayout<PointerMetadata = usize> + Immutable,

Attempts to interpret the suffix of the given source as a &Self with a DST length equal to count.

This method attempts to return a reference to the suffix of source interpreted as a Self with count trailing elements, and a reference to the preceding bytes. If the length of source is less than the size of Self with count elements, if the suffix of source is not appropriately aligned, or if the suffix of source does not contain a valid instance of Self, this returns Err. If Self: Unaligned, you can infallibly discard the alignment error.

§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
    marshmallows: [[u8; 2]],
}

let bytes = &[123, 0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7][..];

let (prefix, packet) = Packet::try_ref_from_suffix_with_elems(bytes, 3).unwrap();

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);
assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
assert_eq!(prefix, &[123u8][..]);

// These bytes are not valid instance of `Packet`.
let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 77, 240, 0xC0, 0xC0][..];
assert!(Packet::try_ref_from_suffix_with_elems(bytes, 3).is_err());

Since an explicit count is provided, this method supports types with zero-sized trailing slice elements. Methods such as try_ref_from_prefix which do not take an explicit count do not support such types.

use core::num::NonZeroU16;
use zerocopy::*;

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

let src = 0xCAFEu16.as_bytes();
let (_, zsty) = ZSTy::try_ref_from_suffix_with_elems(src, 42).unwrap();
assert_eq!(zsty.trailing_dst.len(), 42);
Source

fn try_mut_from_bytes_with_elems( source: &mut [u8], count: usize, ) -> Result<&mut Self, TryCastError<&mut [u8], Self>>
where Self: KnownLayout<PointerMetadata = usize>,

Attempts to interpret the given source as a &mut Self with a DST length equal to count.

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

§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes, KnownLayout)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes, KnownLayout)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
    marshmallows: [[u8; 2]],
}

let bytes = &mut [0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7][..];

let packet = Packet::try_mut_from_bytes_with_elems(bytes, 3).unwrap();

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);
assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);

packet.temperature = 111;

assert_eq!(bytes, [0xC0, 0xC0, 240, 111, 2, 3, 4, 5, 6, 7]);

// These bytes are not valid instance of `Packet`.
let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 77, 240, 0xC0, 0xC0][..];
assert!(Packet::try_mut_from_bytes_with_elems(bytes, 3).is_err());

Since an explicit count is provided, this method supports types with zero-sized trailing slice elements. Methods such as try_mut_from_bytes which do not take an explicit count do not support such types.

use core::num::NonZeroU16;
use zerocopy::*;

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

let mut src = 0xCAFEu16;
let src = src.as_mut_bytes();
let zsty = ZSTy::try_mut_from_bytes_with_elems(src, 42).unwrap();
assert_eq!(zsty.trailing_dst.len(), 42);
Source

fn try_mut_from_prefix_with_elems( source: &mut [u8], count: usize, ) -> Result<(&mut Self, &mut [u8]), TryCastError<&mut [u8], Self>>
where Self: KnownLayout<PointerMetadata = usize>,

Attempts to interpret the prefix of the given source as a &mut Self with a DST length equal to count.

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

§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes, KnownLayout)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes, KnownLayout)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
    marshmallows: [[u8; 2]],
}

let bytes = &mut [0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7, 8][..];

let (packet, suffix) = Packet::try_mut_from_prefix_with_elems(bytes, 3).unwrap();

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);
assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
assert_eq!(suffix, &[8u8][..]);

packet.temperature = 111;
suffix[0] = 222;

assert_eq!(bytes, [0xC0, 0xC0, 240, 111, 2, 3, 4, 5, 6, 7, 222]);

// These bytes are not valid instance of `Packet`.
let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 77, 240, 0xC0, 0xC0][..];
assert!(Packet::try_mut_from_prefix_with_elems(bytes, 3).is_err());

Since an explicit count is provided, this method supports types with zero-sized trailing slice elements. Methods such as try_mut_from_prefix which do not take an explicit count do not support such types.

use core::num::NonZeroU16;
use zerocopy::*;

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

let mut src = 0xCAFEu16;
let src = src.as_mut_bytes();
let (zsty, _) = ZSTy::try_mut_from_prefix_with_elems(src, 42).unwrap();
assert_eq!(zsty.trailing_dst.len(), 42);
Source

fn try_mut_from_suffix_with_elems( source: &mut [u8], count: usize, ) -> Result<(&mut [u8], &mut Self), TryCastError<&mut [u8], Self>>
where Self: KnownLayout<PointerMetadata = usize>,

Attempts to interpret the suffix of the given source as a &mut Self with a DST length equal to count.

This method attempts to return a reference to the suffix of source interpreted as a Self with count trailing elements, and a reference to the preceding bytes. If the length of source is less than the size of Self with count elements, if the suffix of source is not appropriately aligned, or if the suffix of source does not contain a valid instance of Self, this returns Err. If Self: Unaligned, you can infallibly discard the alignment error.

§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes, KnownLayout)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes, KnownLayout)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
    marshmallows: [[u8; 2]],
}

let bytes = &mut [123, 0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7][..];

let (prefix, packet) = Packet::try_mut_from_suffix_with_elems(bytes, 3).unwrap();

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);
assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
assert_eq!(prefix, &[123u8][..]);

prefix[0] = 111;
packet.temperature = 222;

assert_eq!(bytes, [111, 0xC0, 0xC0, 240, 222, 2, 3, 4, 5, 6, 7]);

// These bytes are not valid instance of `Packet`.
let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 77, 240, 0xC0, 0xC0][..];
assert!(Packet::try_mut_from_suffix_with_elems(bytes, 3).is_err());

Since an explicit count is provided, this method supports types with zero-sized trailing slice elements. Methods such as try_mut_from_prefix which do not take an explicit count do not support such types.

use core::num::NonZeroU16;
use zerocopy::*;

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

let mut src = 0xCAFEu16;
let src = src.as_mut_bytes();
let (_, zsty) = ZSTy::try_mut_from_suffix_with_elems(src, 42).unwrap();
assert_eq!(zsty.trailing_dst.len(), 42);
Source

fn try_read_from_bytes(source: &[u8]) -> Result<Self, TryReadError<&[u8], Self>>
where Self: Sized,

Attempts to read the given source as a Self.

If source.len() != size_of::<Self>() or the bytes are not a valid instance of Self, this returns Err.

§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the bytes `0xC0C0`.
#[derive(TryFromBytes)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
}

let bytes = &[0xC0, 0xC0, 240, 77][..];

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

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);

// These bytes are not valid instance of `Packet`.
let bytes = &mut [0x10, 0xC0, 240, 77][..];
assert!(Packet::try_read_from_bytes(bytes).is_err());
Source

fn try_read_from_prefix( source: &[u8], ) -> Result<(Self, &[u8]), TryReadError<&[u8], Self>>
where Self: Sized,

Attempts to read a Self from the prefix of the given source.

This attempts to read a Self from the first size_of::<Self>() bytes of source, returning that Self and any remaining bytes. If source.len() < size_of::<Self>() or the bytes are not a valid instance of Self, it returns Err.

§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the bytes `0xC0C0`.
#[derive(TryFromBytes)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
}

// These are more bytes than are needed to encode a `Packet`.
let bytes = &[0xC0, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5, 6][..];

let (packet, suffix) = Packet::try_read_from_prefix(bytes).unwrap();

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);
assert_eq!(suffix, &[0u8, 1, 2, 3, 4, 5, 6][..]);

// These bytes are not valid instance of `Packet`.
let bytes = &[0x10, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5, 6][..];
assert!(Packet::try_read_from_prefix(bytes).is_err());
Source

fn try_read_from_suffix( source: &[u8], ) -> Result<(&[u8], Self), TryReadError<&[u8], Self>>
where Self: Sized,

Attempts to read a Self from the suffix of the given source.

This attempts to read a Self from the last size_of::<Self>() bytes of source, returning that Self and any preceding bytes. If source.len() < size_of::<Self>() or the bytes are not a valid instance of Self, it returns Err.

§Examples
use zerocopy::TryFromBytes;

// The only valid value of this type is the byte `0xC0`
#[derive(TryFromBytes)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

// The only valid value of this type is the bytes `0xC0C0`.
#[derive(TryFromBytes)]
#[repr(C)]
struct C0C0(C0, C0);

#[derive(TryFromBytes)]
#[repr(C)]
struct Packet {
    magic_number: C0C0,
    mug_size: u8,
    temperature: u8,
}

// These are more bytes than are needed to encode a `Packet`.
let bytes = &[0, 1, 2, 3, 4, 5, 0xC0, 0xC0, 240, 77][..];

let (prefix, packet) = Packet::try_read_from_suffix(bytes).unwrap();

assert_eq!(packet.mug_size, 240);
assert_eq!(packet.temperature, 77);
assert_eq!(prefix, &[0u8, 1, 2, 3, 4, 5][..]);

// These bytes are not valid instance of `Packet`.
let bytes = &[0, 1, 2, 3, 4, 5, 0x10, 0xC0, 240, 77][..];
assert!(Packet::try_read_from_suffix(bytes).is_err());

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 TryFromBytes for Option<NonZeroI8>

Source§

impl TryFromBytes for Option<NonZeroI16>

Source§

impl TryFromBytes for Option<NonZeroI32>

Source§

impl TryFromBytes for Option<NonZeroI64>

Source§

impl TryFromBytes for Option<NonZeroI128>

Source§

impl TryFromBytes for Option<NonZeroIsize>

Source§

impl TryFromBytes for Option<NonZeroU8>

Source§

impl TryFromBytes for Option<NonZeroU16>

Source§

impl TryFromBytes for Option<NonZeroU32>

Source§

impl TryFromBytes for Option<NonZeroU64>

Source§

impl TryFromBytes for Option<NonZeroU128>

Source§

impl TryFromBytes for Option<NonZeroUsize>

Source§

impl TryFromBytes for bool

Source§

impl TryFromBytes for char

Source§

impl TryFromBytes for f32

Source§

impl TryFromBytes for f64

Source§

impl TryFromBytes for i8

Source§

impl TryFromBytes for i16

Source§

impl TryFromBytes for i32

Source§

impl TryFromBytes for i64

Source§

impl TryFromBytes for i128

Source§

impl TryFromBytes for isize

Source§

impl TryFromBytes for str

Source§

impl TryFromBytes for u8

Source§

impl TryFromBytes for u16

Source§

impl TryFromBytes for u32

Source§

impl TryFromBytes for u64

Source§

impl TryFromBytes for u128

Source§

impl TryFromBytes for ()

Source§

impl TryFromBytes for usize

Source§

impl TryFromBytes for AtomicBool

Source§

impl TryFromBytes for AtomicI8

Source§

impl TryFromBytes for AtomicI16

Source§

impl TryFromBytes for AtomicI32

Source§

impl TryFromBytes for AtomicI64

Source§

impl TryFromBytes for AtomicIsize

Source§

impl TryFromBytes for AtomicU8

Source§

impl TryFromBytes for AtomicU16

Source§

impl TryFromBytes for AtomicU32

Source§

impl TryFromBytes for AtomicU64

Source§

impl TryFromBytes for AtomicUsize

Source§

impl TryFromBytes for NonZeroI8

Source§

impl TryFromBytes for NonZeroI16

Source§

impl TryFromBytes for NonZeroI32

Source§

impl TryFromBytes for NonZeroI64

Source§

impl TryFromBytes for NonZeroI128

Source§

impl TryFromBytes for NonZeroIsize

Source§

impl TryFromBytes for NonZeroU8

Source§

impl TryFromBytes for NonZeroU16

Source§

impl TryFromBytes for NonZeroU32

Source§

impl TryFromBytes for NonZeroU64

Source§

impl TryFromBytes for NonZeroU128

Source§

impl TryFromBytes for NonZeroUsize

Source§

impl<A, B, C, D, E, F, G, H, I, J, K, L, M> TryFromBytes for Option<fn(_: A, _: B, _: C, _: D, _: E, _: F, _: G, _: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<A, B, C, D, E, F, G, H, I, J, K, L, M> TryFromBytes for Option<extern "C" fn(_: A, _: B, _: C, _: D, _: E, _: F, _: G, _: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<B, C, D, E, F, G, H, I, J, K, L, M> TryFromBytes for Option<fn(_: B, _: C, _: D, _: E, _: F, _: G, _: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<B, C, D, E, F, G, H, I, J, K, L, M> TryFromBytes for Option<extern "C" fn(_: B, _: C, _: D, _: E, _: F, _: G, _: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<C, D, E, F, G, H, I, J, K, L, M> TryFromBytes for Option<fn(_: C, _: D, _: E, _: F, _: G, _: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<C, D, E, F, G, H, I, J, K, L, M> TryFromBytes for Option<extern "C" fn(_: C, _: D, _: E, _: F, _: G, _: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<D, E, F, G, H, I, J, K, L, M> TryFromBytes for Option<fn(_: D, _: E, _: F, _: G, _: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<D, E, F, G, H, I, J, K, L, M> TryFromBytes for Option<extern "C" fn(_: D, _: E, _: F, _: G, _: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<E, F, G, H, I, J, K, L, M> TryFromBytes for Option<fn(_: E, _: F, _: G, _: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<E, F, G, H, I, J, K, L, M> TryFromBytes for Option<extern "C" fn(_: E, _: F, _: G, _: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<F, G, H, I, J, K, L, M> TryFromBytes for Option<fn(_: F, _: G, _: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<F, G, H, I, J, K, L, M> TryFromBytes for Option<extern "C" fn(_: F, _: G, _: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<G, H, I, J, K, L, M> TryFromBytes for Option<fn(_: G, _: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<G, H, I, J, K, L, M> TryFromBytes for Option<extern "C" fn(_: G, _: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<H, I, J, K, L, M> TryFromBytes for Option<fn(_: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<H, I, J, K, L, M> TryFromBytes for Option<extern "C" fn(_: H, _: I, _: J, _: K, _: L) -> M>

Source§

impl<I, J, K, L, M> TryFromBytes for Option<fn(_: I, _: J, _: K, _: L) -> M>

Source§

impl<I, J, K, L, M> TryFromBytes for Option<extern "C" fn(_: I, _: J, _: K, _: L) -> M>

Source§

impl<J, K, L, M> TryFromBytes for Option<fn(_: J, _: K, _: L) -> M>

Source§

impl<J, K, L, M> TryFromBytes for Option<extern "C" fn(_: J, _: K, _: L) -> M>

Source§

impl<K, L, M> TryFromBytes for Option<fn(_: K, _: L) -> M>

Source§

impl<K, L, M> TryFromBytes for Option<extern "C" fn(_: K, _: L) -> M>

Source§

impl<L, M> TryFromBytes for Option<fn(_: L) -> M>

Source§

impl<L, M> TryFromBytes for Option<extern "C" fn(_: L) -> M>

Source§

impl<M> TryFromBytes for Option<fn() -> M>

Source§

impl<M> TryFromBytes for Option<extern "C" fn() -> M>

Source§

impl<T> TryFromBytes for Option<&T>

Source§

impl<T> TryFromBytes for Option<&mut T>

Source§

impl<T> TryFromBytes for Option<NonNull<T>>

Source§

impl<T> TryFromBytes for *const T

Source§

impl<T> TryFromBytes for *mut T

Source§

impl<T> TryFromBytes for AtomicPtr<T>

Source§

impl<T> TryFromBytes for MaybeUninit<T>

Source§

impl<T: TryFromBytes + ?Sized> TryFromBytes for UnsafeCell<T>

Source§

impl<T: TryFromBytes> TryFromBytes for [T]

Source§

impl<T: TryFromBytes> TryFromBytes for Wrapping<T>

Source§

impl<T: TryFromBytes, const N: usize> TryFromBytes for [T; N]

Source§

impl<T: ?Sized + TryFromBytes> TryFromBytes for ManuallyDrop<T>

Source§

impl<T: ?Sized> TryFromBytes for PhantomData<T>

Implementors§