TryFromBytes

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 + IntoBytes { ... } fn try_mut_from_prefix( source: &mut [u8], ) -> Result<(&mut Self, &mut [u8]), TryCastError<&mut [u8], Self>> where Self: KnownLayout + IntoBytes { ... } fn try_mut_from_suffix( source: &mut [u8], ) -> Result<(&mut [u8], &mut Self), TryCastError<&mut [u8], Self>> where Self: KnownLayout + IntoBytes { ... } 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> + IntoBytes { ... } 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> + IntoBytes { ... } 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> + IntoBytes { ... } 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 documented 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());
§ Code Generation

This abstraction is safe and cheap, but does not necessarily have zero runtime cost. The codegen you experience in practice will depend on optimization level, the layout of the destination type, and what the compiler can prove about the source.

The below examples illustrate typical codegen for increasingly complex types:

Sized
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(2))]
pub struct Packet<Magic> {
   magic_number: Magic,
   mug_size: u8,
   temperature: u8,
   marshmallows: [u8; 2],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_static_size.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_bytes_static_size(source: &[u8]) -> Option<&format::CocoPacket> {
   zerocopy::TryFromBytes::try_ref_from_bytes(source).ok()
}
Assembly
bench_try_ref_from_bytes_static_size:
   mov rax, rdi
   cmp rsi, 6
   setne cl
   or cl, al
   test cl, 1
   jne .LBB5_2
   cmp word ptr [rax], -16192
   je .LBB5_3
.LBB5_2:
   xor eax, eax
.LBB5_3:
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1000
Total Cycles:      308
Total uOps:        1100

Dispatch Width:    4
uOps Per Cycle:    3.57
IPC:               3.25
Block RThroughput: 3.0


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.33                        mov	rax, rdi
1      1     0.33                        cmp	rsi, 6
1      1     0.50                        setne	cl
1      1     0.33                        or	cl, al
1      1     0.33                        test	cl, 1
1      1     1.00                        jne	.LBB5_2
2      6     0.50    *                   cmp	word ptr [rax], -16192
1      1     1.00                        je	.LBB5_3
1      0     0.25                        xor	eax, eax
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     2.98   2.98    -     3.04   0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.02   0.97    -     0.01    -      -     mov	rax, rdi
-      -     0.02   0.98    -      -      -      -     cmp	rsi, 6
-      -     1.00    -      -      -      -      -     setne	cl
-      -     0.97   0.02    -     0.01    -      -     or	cl, al
-      -     0.96   0.03    -     0.01    -      -     test	cl, 1
-      -      -      -      -     1.00    -      -     jne	.LBB5_2
-      -     0.01   0.98    -     0.01   0.50   0.50   cmp	word ptr [rax], -16192
-      -      -      -      -     1.00    -      -     je	.LBB5_3
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -      -      -     1.00    -      -     ret
Unsized
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(2))]
pub struct Packet<Magic> {
   magic_number: Magic,
   mug_size: u8,
   temperature: u8,
   marshmallows: [[u8; 2]],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_dynamic_size.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_bytes_dynamic_size(source: &[u8]) -> Option<&format::CocoPacket> {
   zerocopy::TryFromBytes::try_ref_from_bytes(source).ok()
}
Assembly
bench_try_ref_from_bytes_dynamic_size:
   mov rdx, rsi
   mov rax, rdi
   cmp rsi, 4
   setb cl
   or cl, al
   test cl, 1
   jne .LBB5_4
   lea rcx, [rdx - 4]
   mov rsi, rcx
   and rsi, -2
   add rsi, 4
   cmp rdx, rsi
   jne .LBB5_4
   cmp word ptr [rax], -16192
   jne .LBB5_4
   shr rcx
   mov rdx, rcx
   ret
.LBB5_4:
   xor eax, eax
   ret
Machine Code Analysis
Iterations:        100
Instructions:      2000
Total Cycles:      639
Total uOps:        2100

Dispatch Width:    4
uOps Per Cycle:    3.29
IPC:               3.13
Block RThroughput: 5.3


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.33                        mov	rdx, rsi
1      1     0.33                        mov	rax, rdi
1      1     0.33                        cmp	rsi, 4
1      1     0.50                        setb	cl
1      1     0.33                        or	cl, al
1      1     0.33                        test	cl, 1
1      1     1.00                        jne	.LBB5_4
1      1     0.50                        lea	rcx, [rdx - 4]
1      1     0.33                        mov	rsi, rcx
1      1     0.33                        and	rsi, -2
1      1     0.33                        add	rsi, 4
1      1     0.33                        cmp	rdx, rsi
1      1     1.00                        jne	.LBB5_4
2      6     0.50    *                   cmp	word ptr [rax], -16192
1      1     1.00                        jne	.LBB5_4
1      1     0.50                        shr	rcx
1      1     0.33                        mov	rdx, rcx
1      1     1.00                  U     ret
1      0     0.25                        xor	eax, eax
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     6.32   6.32    -     6.36   0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.33   0.66    -     0.01    -      -     mov	rdx, rsi
-      -     0.66   0.34    -      -      -      -     mov	rax, rdi
-      -     0.34   0.66    -      -      -      -     cmp	rsi, 4
-      -     0.99    -      -     0.01    -      -     setb	cl
-      -     0.01   0.99    -      -      -      -     or	cl, al
-      -      -     1.00    -      -      -      -     test	cl, 1
-      -      -      -      -     1.00    -      -     jne	.LBB5_4
-      -     0.66   0.34    -      -      -      -     lea	rcx, [rdx - 4]
-      -     0.33   0.66    -     0.01    -      -     mov	rsi, rcx
-      -     1.00    -      -      -      -      -     and	rsi, -2
-      -     0.66   0.34    -      -      -      -     add	rsi, 4
-      -      -     1.00    -      -      -      -     cmp	rdx, rsi
-      -      -      -      -     1.00    -      -     jne	.LBB5_4
-      -      -      -      -     1.00   0.50   0.50   cmp	word ptr [rax], -16192
-      -      -      -      -     1.00    -      -     jne	.LBB5_4
-      -     0.67    -      -     0.33    -      -     shr	rcx
-      -     0.67   0.33    -      -      -      -     mov	rdx, rcx
-      -      -      -      -     1.00    -      -     ret
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -      -      -     1.00    -      -     ret
Dynamically Padded
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(4))]
pub struct Packet<Magic> {
   magic_number: Magic,
   milk: u8,
   mug_size: u8,
   temperature: [u8; 5],
   marshmallows: [[u8; 3]],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_dynamic_padding.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_bytes_dynamic_padding(source: &[u8]) -> Option<&format::CocoPacket> {
   zerocopy::TryFromBytes::try_ref_from_bytes(source).ok()
}
Assembly
bench_try_ref_from_bytes_dynamic_padding:
   test dil, 3
   jne .LBB5_4
   movabs rax, 9223372036854775804
   and rax, rsi
   cmp rax, 9
   jb .LBB5_4
   add rax, -9
   movabs rcx, -6148914691236517205
   mul rcx
   shr rdx
   lea rax, [rdx + 2*rdx]
   or rax, 3
   add rax, 9
   cmp rsi, rax
   jne .LBB5_4
   cmp word ptr [rdi], -16192
   je .LBB5_5
.LBB5_4:
   xor edi, edi
   mov rdx, rsi
.LBB5_5:
   mov rax, rdi
   ret
Machine Code Analysis
Iterations:        100
Instructions:      2100
Total Cycles:      709
Total uOps:        2300

Dispatch Width:    4
uOps Per Cycle:    3.24
IPC:               2.96
Block RThroughput: 5.8


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.33                        test	dil, 3
1      1     1.00                        jne	.LBB5_4
1      1     0.33                        movabs	rax, 9223372036854775804
1      1     0.33                        and	rax, rsi
1      1     0.33                        cmp	rax, 9
1      1     1.00                        jb	.LBB5_4
1      1     0.33                        add	rax, -9
1      1     0.33                        movabs	rcx, -6148914691236517205
2      4     1.00                        mul	rcx
1      1     0.50                        shr	rdx
1      1     0.50                        lea	rax, [rdx + 2*rdx]
1      1     0.33                        or	rax, 3
1      1     0.33                        add	rax, 9
1      1     0.33                        cmp	rsi, rax
1      1     1.00                        jne	.LBB5_4
2      6     0.50    *                   cmp	word ptr [rdi], -16192
1      1     1.00                        je	.LBB5_5
1      0     0.25                        xor	edi, edi
1      1     0.33                        mov	rdx, rsi
1      1     0.33                        mov	rax, rdi
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     6.98   6.99    -     7.03   0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.48   0.51    -     0.01    -      -     test	dil, 3
-      -      -      -      -     1.00    -      -     jne	.LBB5_4
-      -     0.51   0.49    -      -      -      -     movabs	rax, 9223372036854775804
-      -     0.01   0.99    -      -      -      -     and	rax, rsi
-      -     0.51   0.49    -      -      -      -     cmp	rax, 9
-      -      -      -      -     1.00    -      -     jb	.LBB5_4
-      -     0.98    -      -     0.02    -      -     add	rax, -9
-      -     0.98   0.02    -      -      -      -     movabs	rcx, -6148914691236517205
-      -     1.00   1.00    -      -      -      -     mul	rcx
-      -     0.99    -      -     0.01    -      -     shr	rdx
-      -      -     1.00    -      -      -      -     lea	rax, [rdx + 2*rdx]
-      -      -     0.51    -     0.49    -      -     or	rax, 3
-      -     0.01   0.49    -     0.50    -      -     add	rax, 9
-      -      -     0.02    -     0.98    -      -     cmp	rsi, rax
-      -      -      -      -     1.00    -      -     jne	.LBB5_4
-      -     0.51   0.49    -      -     0.50   0.50   cmp	word ptr [rdi], -16192
-      -      -      -      -     1.00    -      -     je	.LBB5_5
-      -      -      -      -      -      -      -     xor	edi, edi
-      -     0.50   0.50    -      -      -      -     mov	rdx, rsi
-      -     0.50   0.48    -     0.02    -      -     mov	rax, rdi
-      -      -      -      -     1.00    -      -     ret
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());
§ Code Generation

This abstraction is safe and cheap, but does not necessarily have zero runtime cost. The codegen you experience in practice will depend on optimization level, the layout of the destination type, and what the compiler can prove about the source.

The below examples illustrate typical codegen for increasingly complex types:

Sized
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(2))]
pub struct Packet<Magic> {
   magic_number: Magic,
   mug_size: u8,
   temperature: u8,
   marshmallows: [u8; 2],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_static_size.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_prefix_static_size(source: &[u8]) -> Option<&format::CocoPacket> {
   match zerocopy::TryFromBytes::try_ref_from_prefix(source) {
       Ok((packet, _rest)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_try_ref_from_prefix_static_size:
   cmp rsi, 6
   setb al
   or al, dil
   test al, 1
   jne .LBB5_2
   movzx eax, word ptr [rdi]
   cmp eax, 49344
   mov eax, 2
   cmove rax, rdi
   je .LBB5_3
.LBB5_2:
   xor eax, eax
.LBB5_3:
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1200
Total Cycles:      374
Total uOps:        1300

Dispatch Width:    4
uOps Per Cycle:    3.48
IPC:               3.21
Block RThroughput: 3.3


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.33                        cmp	rsi, 6
1      1     0.50                        setb	al
1      1     0.33                        or	al, dil
1      1     0.33                        test	al, 1
1      1     1.00                        jne	.LBB5_2
1      5     0.50    *                   movzx	eax, word ptr [rdi]
1      1     0.33                        cmp	eax, 49344
1      1     0.33                        mov	eax, 2
2      2     0.67                        cmove	rax, rdi
1      1     1.00                        je	.LBB5_3
1      0     0.25                        xor	eax, eax
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     3.66   3.65    -     3.69   0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.35   0.64    -     0.01    -      -     cmp	rsi, 6
-      -     1.00    -      -      -      -      -     setb	al
-      -     0.02   0.66    -     0.32    -      -     or	al, dil
-      -     0.03   0.65    -     0.32    -      -     test	al, 1
-      -      -      -      -     1.00    -      -     jne	.LBB5_2
-      -      -      -      -      -     0.50   0.50   movzx	eax, word ptr [rdi]
-      -     0.92   0.07    -     0.01    -      -     cmp	eax, 49344
-      -     0.37   0.63    -      -      -      -     mov	eax, 2
-      -     0.97   1.00    -     0.03    -      -     cmove	rax, rdi
-      -      -      -      -     1.00    -      -     je	.LBB5_3
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -      -      -     1.00    -      -     ret
Unsized
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(2))]
pub struct Packet<Magic> {
   magic_number: Magic,
   mug_size: u8,
   temperature: u8,
   marshmallows: [[u8; 2]],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_dynamic_size.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_prefix_dynamic_size(source: &[u8]) -> Option<&format::CocoPacket> {
   match zerocopy::TryFromBytes::try_ref_from_prefix(source) {
       Ok((packet, _rest)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_try_ref_from_prefix_dynamic_size:
   xor edx, edx
   mov eax, 0
   test dil, 1
   jne .LBB5_4
   cmp rsi, 4
   jae .LBB5_3
   mov edx, 1
   xor eax, eax
   ret
.LBB5_3:
   add rsi, -4
   shr rsi
   movzx ecx, word ptr [rdi]
   cmp ecx, 49344
   mov edx, 2
   cmove rdx, rsi
   xor eax, eax
   cmp cx, -16192
   cmove rax, rdi
.LBB5_4:
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1900
Total Cycles:      573
Total uOps:        2100

Dispatch Width:    4
uOps Per Cycle:    3.66
IPC:               3.32
Block RThroughput: 5.3


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      0     0.25                        xor	edx, edx
1      1     0.33                        mov	eax, 0
1      1     0.33                        test	dil, 1
1      1     1.00                        jne	.LBB5_4
1      1     0.33                        cmp	rsi, 4
1      1     1.00                        jae	.LBB5_3
1      1     0.33                        mov	edx, 1
1      0     0.25                        xor	eax, eax
1      1     1.00                  U     ret
1      1     0.33                        add	rsi, -4
1      1     0.50                        shr	rsi
1      5     0.50    *                   movzx	ecx, word ptr [rdi]
1      1     0.33                        cmp	ecx, 49344
1      1     0.33                        mov	edx, 2
2      2     0.67                        cmove	rdx, rsi
1      0     0.25                        xor	eax, eax
1      1     0.33                        cmp	cx, -16192
2      2     0.67                        cmove	rax, rdi
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     5.66   5.67    -     5.67   0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -      -      -      -      -      -      -     xor	edx, edx
-      -     0.30   0.37    -     0.33    -      -     mov	eax, 0
-      -     0.35   0.32    -     0.33    -      -     test	dil, 1
-      -      -      -      -     1.00    -      -     jne	.LBB5_4
-      -     0.32   0.33    -     0.35    -      -     cmp	rsi, 4
-      -      -      -      -     1.00    -      -     jae	.LBB5_3
-      -     0.33   0.35    -     0.32    -      -     mov	edx, 1
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -      -      -     1.00    -      -     ret
-      -     0.34   0.64    -     0.02    -      -     add	rsi, -4
-      -     1.00    -      -      -      -      -     shr	rsi
-      -      -      -      -      -     0.50   0.50   movzx	ecx, word ptr [rdi]
-      -     0.60   0.40    -      -      -      -     cmp	ecx, 49344
-      -     0.05   0.95    -      -      -      -     mov	edx, 2
-      -     1.00   1.00    -      -      -      -     cmove	rdx, rsi
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.37   0.31    -     0.32    -      -     cmp	cx, -16192
-      -     1.00   1.00    -      -      -      -     cmove	rax, rdi
-      -      -      -      -     1.00    -      -     ret
Dynamically Padded
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(4))]
pub struct Packet<Magic> {
   magic_number: Magic,
   milk: u8,
   mug_size: u8,
   temperature: [u8; 5],
   marshmallows: [[u8; 3]],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_dynamic_padding.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_prefix_dynamic_padding(source: &[u8]) -> Option<&format::CocoPacket> {
   match zerocopy::TryFromBytes::try_ref_from_prefix(source) {
       Ok((packet, _rest)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_try_ref_from_prefix_dynamic_padding:
   xor edx, edx
   mov eax, 0
   test dil, 3
   je .LBB5_1
   ret
.LBB5_1:
   movabs rax, 9223372036854775804
   and rsi, rax
   cmp rsi, 9
   jae .LBB5_3
   mov edx, 1
   xor eax, eax
   ret
.LBB5_3:
   add rsi, -9
   movabs rcx, -6148914691236517205
   mov rax, rsi
   mul rcx
   mov rax, rdx
   shr rax
   movzx ecx, word ptr [rdi]
   cmp cx, -16192
   mov edx, 2
   cmove rdx, rax
   xor eax, eax
   cmp ecx, 49344
   cmove rax, rdi
   ret
Machine Code Analysis
Iterations:        100
Instructions:      2600
Total Cycles:      843
Total uOps:        2900

Dispatch Width:    4
uOps Per Cycle:    3.44
IPC:               3.08
Block RThroughput: 7.3


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      0     0.25                        xor	edx, edx
1      1     0.33                        mov	eax, 0
1      1     0.33                        test	dil, 3
1      1     1.00                        je	.LBB5_1
1      1     1.00                  U     ret
1      1     0.33                        movabs	rax, 9223372036854775804
1      1     0.33                        and	rsi, rax
1      1     0.33                        cmp	rsi, 9
1      1     1.00                        jae	.LBB5_3
1      1     0.33                        mov	edx, 1
1      0     0.25                        xor	eax, eax
1      1     1.00                  U     ret
1      1     0.33                        add	rsi, -9
1      1     0.33                        movabs	rcx, -6148914691236517205
1      1     0.33                        mov	rax, rsi
2      4     1.00                        mul	rcx
1      1     0.33                        mov	rax, rdx
1      1     0.50                        shr	rax
1      5     0.50    *                   movzx	ecx, word ptr [rdi]
1      1     0.33                        cmp	cx, -16192
1      1     0.33                        mov	edx, 2
2      2     0.67                        cmove	rdx, rax
1      0     0.25                        xor	eax, eax
1      1     0.33                        cmp	ecx, 49344
2      2     0.67                        cmove	rax, rdi
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     8.33   8.33    -     8.34   0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -      -      -      -      -      -      -     xor	edx, edx
-      -     0.32   0.34    -     0.34    -      -     mov	eax, 0
-      -     0.34   0.33    -     0.33    -      -     test	dil, 3
-      -      -      -      -     1.00    -      -     je	.LBB5_1
-      -      -      -      -     1.00    -      -     ret
-      -     0.35   0.65    -      -      -      -     movabs	rax, 9223372036854775804
-      -     0.96   0.03    -     0.01    -      -     and	rsi, rax
-      -     0.01   0.97    -     0.02    -      -     cmp	rsi, 9
-      -      -      -      -     1.00    -      -     jae	.LBB5_3
-      -     0.67   0.01    -     0.32    -      -     mov	edx, 1
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -      -      -     1.00    -      -     ret
-      -     0.02   0.34    -     0.64    -      -     add	rsi, -9
-      -     0.33   0.66    -     0.01    -      -     movabs	rcx, -6148914691236517205
-      -     0.66   0.34    -      -      -      -     mov	rax, rsi
-      -     1.00   1.00    -      -      -      -     mul	rcx
-      -     0.01   0.99    -      -      -      -     mov	rax, rdx
-      -     0.99    -      -     0.01    -      -     shr	rax
-      -      -      -      -      -     0.50   0.50   movzx	ecx, word ptr [rdi]
-      -     0.33   0.03    -     0.64    -      -     cmp	cx, -16192
-      -     0.01   0.31    -     0.68    -      -     mov	edx, 2
-      -     1.00   1.00    -      -      -      -     cmove	rdx, rax
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.33   0.33    -     0.34    -      -     cmp	ecx, 49344
-      -     1.00   1.00    -      -      -      -     cmove	rax, rdi
-      -      -      -      -     1.00    -      -     ret
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());
§ Code Generation

This abstraction is safe and cheap, but does not necessarily have zero runtime cost. The codegen you experience in practice will depend on optimization level, the layout of the destination type, and what the compiler can prove about the source.

The below examples illustrate typical codegen for increasingly complex types:

Sized
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(2))]
pub struct Packet<Magic> {
   magic_number: Magic,
   mug_size: u8,
   temperature: u8,
   marshmallows: [u8; 2],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_static_size.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_suffix_static_size(source: &[u8]) -> Option<&format::CocoPacket> {
   match zerocopy::TryFromBytes::try_ref_from_suffix(source) {
       Ok((_rest, packet)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_try_ref_from_suffix_static_size:
   lea eax, [rsi + rdi]
   cmp rsi, 6
   setb cl
   or cl, al
   test cl, 1
   je .LBB5_2
   xor eax, eax
   ret
.LBB5_2:
   lea rcx, [rdi + rsi]
   add rcx, -6
   xor eax, eax
   cmp word ptr [rdi + rsi - 6], -16192
   cmove rax, rcx
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1400
Total Cycles:      443
Total uOps:        1600

Dispatch Width:    4
uOps Per Cycle:    3.61
IPC:               3.16
Block RThroughput: 4.0


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.50                        lea	eax, [rsi + rdi]
1      1     0.33                        cmp	rsi, 6
1      1     0.50                        setb	cl
1      1     0.33                        or	cl, al
1      1     0.33                        test	cl, 1
1      1     1.00                        je	.LBB5_2
1      0     0.25                        xor	eax, eax
1      1     1.00                  U     ret
1      1     0.50                        lea	rcx, [rdi + rsi]
1      1     0.33                        add	rcx, -6
1      0     0.25                        xor	eax, eax
2      6     0.50    *                   cmp	word ptr [rdi + rsi - 6], -16192
2      2     0.67                        cmove	rax, rcx
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     4.33   4.33    -     4.34   0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.32   0.68    -      -      -      -     lea	eax, [rsi + rdi]
-      -     0.05   0.94    -     0.01    -      -     cmp	rsi, 6
-      -     1.00    -      -      -      -      -     setb	cl
-      -     0.95   0.05    -      -      -      -     or	cl, al
-      -     0.95   0.02    -     0.03    -      -     test	cl, 1
-      -      -      -      -     1.00    -      -     je	.LBB5_2
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -      -      -     1.00    -      -     ret
-      -     0.04   0.96    -      -      -      -     lea	rcx, [rdi + rsi]
-      -     0.02   0.97    -     0.01    -      -     add	rcx, -6
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.03   0.66    -     0.31   0.50   0.50   cmp	word ptr [rdi + rsi - 6], -16192
-      -     0.97   0.05    -     0.98    -      -     cmove	rax, rcx
-      -      -      -      -     1.00    -      -     ret
Unsized
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(2))]
pub struct Packet<Magic> {
   magic_number: Magic,
   mug_size: u8,
   temperature: u8,
   marshmallows: [[u8; 2]],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_dynamic_size.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_suffix_dynamic_size(source: &[u8]) -> Option<&format::CocoPacket> {
   match zerocopy::TryFromBytes::try_ref_from_suffix(source) {
       Ok((_rest, packet)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_try_ref_from_suffix_dynamic_size:
   lea eax, [rsi + rdi]
   cmp rsi, 4
   setb cl
   or cl, al
   test cl, 1
   je .LBB5_2
   xor eax, eax
   ret
.LBB5_2:
   lea rdx, [rsi - 4]
   shr rdx
   and esi, 1
   lea rcx, [rdi + rsi]
   xor eax, eax
   cmp word ptr [rdi + rsi], -16192
   cmove rax, rcx
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1600
Total Cycles:      510
Total uOps:        1800

Dispatch Width:    4
uOps Per Cycle:    3.53
IPC:               3.14
Block RThroughput: 4.5


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.50                        lea	eax, [rsi + rdi]
1      1     0.33                        cmp	rsi, 4
1      1     0.50                        setb	cl
1      1     0.33                        or	cl, al
1      1     0.33                        test	cl, 1
1      1     1.00                        je	.LBB5_2
1      0     0.25                        xor	eax, eax
1      1     1.00                  U     ret
1      1     0.50                        lea	rdx, [rsi - 4]
1      1     0.50                        shr	rdx
1      1     0.33                        and	esi, 1
1      1     0.50                        lea	rcx, [rdi + rsi]
1      0     0.25                        xor	eax, eax
2      6     0.50    *                   cmp	word ptr [rdi + rsi], -16192
2      2     0.67                        cmove	rax, rcx
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     4.99   5.00    -     5.01   0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.98   0.02    -      -      -      -     lea	eax, [rsi + rdi]
-      -      -     0.98    -     0.02    -      -     cmp	rsi, 4
-      -     1.00    -      -      -      -      -     setb	cl
-      -     0.01   0.99    -      -      -      -     or	cl, al
-      -     0.01   0.07    -     0.92    -      -     test	cl, 1
-      -      -      -      -     1.00    -      -     je	.LBB5_2
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -      -      -     1.00    -      -     ret
-      -     0.93   0.07    -      -      -      -     lea	rdx, [rsi - 4]
-      -     0.93    -      -     0.07    -      -     shr	rdx
-      -     0.06   0.93    -     0.01    -      -     and	esi, 1
-      -     0.07   0.93    -      -      -      -     lea	rcx, [rdi + rsi]
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -     0.01    -     0.99   0.50   0.50   cmp	word ptr [rdi + rsi], -16192
-      -     1.00   1.00    -      -      -      -     cmove	rax, rcx
-      -      -      -      -     1.00    -      -     ret
Dynamically Padded
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(4))]
pub struct Packet<Magic> {
   magic_number: Magic,
   milk: u8,
   mug_size: u8,
   temperature: [u8; 5],
   marshmallows: [[u8; 3]],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_dynamic_padding.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_suffix_dynamic_padding(source: &[u8]) -> Option<&format::CocoPacket> {
   match zerocopy::TryFromBytes::try_ref_from_suffix(source) {
       Ok((_rest, packet)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_try_ref_from_suffix_dynamic_padding:
   lea eax, [rsi + rdi]
   test al, 3
   jne .LBB5_1
   movabs rax, 9223372036854775804
   and rax, rsi
   cmp rax, 9
   jae .LBB5_3
.LBB5_1:
   xor eax, eax
   ret
.LBB5_3:
   add rax, -9
   movabs rcx, -6148914691236517205
   mul rcx
   shr rdx
   lea rcx, [rdx + 2*rdx]
   sub rsi, rcx
   or rcx, -4
   add rsi, rdi
   lea rdi, [rcx + rsi]
   add rdi, -8
   xor eax, eax
   cmp word ptr [rcx + rsi - 8], -16192
   cmove rax, rdi
   ret
Machine Code Analysis
Iterations:        100
Instructions:      2300
Total Cycles:      791
Total uOps:        2600

Dispatch Width:    4
uOps Per Cycle:    3.29
IPC:               2.91
Block RThroughput: 6.5


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.50                        lea	eax, [rsi + rdi]
1      1     0.33                        test	al, 3
1      1     1.00                        jne	.LBB5_1
1      1     0.33                        movabs	rax, 9223372036854775804
1      1     0.33                        and	rax, rsi
1      1     0.33                        cmp	rax, 9
1      1     1.00                        jae	.LBB5_3
1      0     0.25                        xor	eax, eax
1      1     1.00                  U     ret
1      1     0.33                        add	rax, -9
1      1     0.33                        movabs	rcx, -6148914691236517205
2      4     1.00                        mul	rcx
1      1     0.50                        shr	rdx
1      1     0.50                        lea	rcx, [rdx + 2*rdx]
1      1     0.33                        sub	rsi, rcx
1      1     0.33                        or	rcx, -4
1      1     0.33                        add	rsi, rdi
1      1     0.50                        lea	rdi, [rcx + rsi]
1      1     0.33                        add	rdi, -8
1      0     0.25                        xor	eax, eax
2      6     0.50    *                   cmp	word ptr [rcx + rsi - 8], -16192
2      2     0.67                        cmove	rax, rdi
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     7.70   7.58    -     7.72   0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.26   0.74    -      -      -      -     lea	eax, [rsi + rdi]
-      -     0.19   0.28    -     0.53    -      -     test	al, 3
-      -      -      -      -     1.00    -      -     jne	.LBB5_1
-      -     0.93   0.06    -     0.01    -      -     movabs	rax, 9223372036854775804
-      -     0.81   0.14    -     0.05    -      -     and	rax, rsi
-      -     0.55   0.43    -     0.02    -      -     cmp	rax, 9
-      -      -      -      -     1.00    -      -     jae	.LBB5_3
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -      -      -     1.00    -      -     ret
-      -     0.42   0.56    -     0.02    -      -     add	rax, -9
-      -     0.67   0.30    -     0.03    -      -     movabs	rcx, -6148914691236517205
-      -     1.00   1.00    -      -      -      -     mul	rcx
-      -     0.71    -      -     0.29    -      -     shr	rdx
-      -     0.32   0.68    -      -      -      -     lea	rcx, [rdx + 2*rdx]
-      -     0.57   0.04    -     0.39    -      -     sub	rsi, rcx
-      -     0.28   0.67    -     0.05    -      -     or	rcx, -4
-      -     0.29   0.29    -     0.42    -      -     add	rsi, rdi
-      -     0.02   0.98    -      -      -      -     lea	rdi, [rcx + rsi]
-      -     0.02   0.41    -     0.57    -      -     add	rdi, -8
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.57   0.01    -     0.42   0.50   0.50   cmp	word ptr [rcx + rsi - 8], -16192
-      -     0.09   0.99    -     0.92    -      -     cmove	rax, rdi
-      -      -      -      -     1.00    -      -     ret
Source

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

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, IntoBytes, KnownLayout)]
#[repr(C, packed)]
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, IntoBytes, KnownLayout)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

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

#[derive(TryFromBytes, IntoBytes, KnownLayout)]
#[repr(C, packed)]
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());
§ Code Generation

See TryFromBytes::try_ref_from_bytes.

Source

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

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, IntoBytes, KnownLayout)]
#[repr(C, packed)]
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, IntoBytes, KnownLayout)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

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

#[derive(TryFromBytes, IntoBytes, KnownLayout)]
#[repr(C, packed)]
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());
§ Code Generation

See TryFromBytes::try_ref_from_prefix.

Source

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

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, IntoBytes, KnownLayout)]
#[repr(C, packed)]
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, IntoBytes, KnownLayout)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

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

#[derive(TryFromBytes, IntoBytes, KnownLayout)]
#[repr(C, packed)]
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());
§ Code Generation

See TryFromBytes::try_ref_from_suffix.

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);
§ Code Generation

This abstraction is safe and cheap, but does not necessarily have zero runtime cost. The codegen you experience in practice will depend on optimization level, the layout of the destination type, and what the compiler can prove about the source.

The below examples illustrate typical codegen for increasingly complex types:

Unsized
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(2))]
pub struct Packet<Magic> {
   magic_number: Magic,
   mug_size: u8,
   temperature: u8,
   marshmallows: [[u8; 2]],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_dynamic_size.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_bytes_with_elems_dynamic_size(
   source: &[u8],
   count: usize,
) -> Option<&format::CocoPacket> {
   zerocopy::TryFromBytes::try_ref_from_bytes_with_elems(source, count).ok()
}
Assembly
bench_try_ref_from_bytes_with_elems_dynamic_size:
   movabs rax, 9223372036854775805
   cmp rdx, rax
   seta cl
   mov rax, rdi
   or dil, cl
   test dil, 1
   jne .LBB5_3
   lea rcx, [2*rdx + 4]
   cmp rsi, rcx
   jne .LBB5_3
   cmp word ptr [rax], -16192
   je .LBB5_4
.LBB5_3:
   xor eax, eax
   mov rdx, rsi
.LBB5_4:
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1500
Total Cycles:      507
Total uOps:        1700

Dispatch Width:    4
uOps Per Cycle:    3.35
IPC:               2.96
Block RThroughput: 4.3


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.33                        movabs	rax, 9223372036854775805
1      1     0.33                        cmp	rdx, rax
2      2     1.00                        seta	cl
1      1     0.33                        mov	rax, rdi
1      1     0.33                        or	dil, cl
1      1     0.33                        test	dil, 1
1      1     1.00                        jne	.LBB5_3
1      1     0.50                        lea	rcx, [2*rdx + 4]
1      1     0.33                        cmp	rsi, rcx
1      1     1.00                        jne	.LBB5_3
2      6     0.50    *                   cmp	word ptr [rax], -16192
1      1     1.00                        je	.LBB5_4
1      0     0.25                        xor	eax, eax
1      1     0.33                        mov	rdx, rsi
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     4.98   4.99    -     5.03   0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -      -     0.99    -     0.01    -      -     movabs	rax, 9223372036854775805
-      -     0.50   0.50    -      -      -      -     cmp	rdx, rax
-      -     1.96    -      -     0.04    -      -     seta	cl
-      -     0.01   0.99    -      -      -      -     mov	rax, rdi
-      -     1.00    -      -      -      -      -     or	dil, cl
-      -     0.99   0.01    -      -      -      -     test	dil, 1
-      -      -      -      -     1.00    -      -     jne	.LBB5_3
-      -     0.01   0.99    -      -      -      -     lea	rcx, [2*rdx + 4]
-      -     0.02   0.49    -     0.49    -      -     cmp	rsi, rcx
-      -      -      -      -     1.00    -      -     jne	.LBB5_3
-      -      -     0.51    -     0.49   0.50   0.50   cmp	word ptr [rax], -16192
-      -      -      -      -     1.00    -      -     je	.LBB5_4
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.49   0.51    -      -      -      -     mov	rdx, rsi
-      -      -      -      -     1.00    -      -     ret
Dynamically Padded
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(4))]
pub struct Packet<Magic> {
   magic_number: Magic,
   milk: u8,
   mug_size: u8,
   temperature: [u8; 5],
   marshmallows: [[u8; 3]],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_dynamic_padding.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_bytes_with_elems_dynamic_padding(
   source: &[u8],
   count: usize,
) -> Option<&format::CocoPacket> {
   zerocopy::TryFromBytes::try_ref_from_bytes_with_elems(source, count).ok()
}
Assembly
bench_try_ref_from_bytes_with_elems_dynamic_padding:
   mov rcx, rdx
   mov edx, 3
   mov rax, rcx
   mul rdx
   jo .LBB5_8
   mov rdx, rax
   cmp rax, -10
   ja .LBB5_8
   mov eax, edx
   not eax
   and eax, 3
   lea r8, [rax + rdx]
   add r8, 9
   xor eax, eax
   cmp rsi, r8
   jne .LBB5_6
   mov r9d, edi
   and r9d, 3
   jne .LBB5_6
   add rdx, 9
   cmp r8, rdx
   jb .LBB5_6
   movzx edx, word ptr [rdi]
   cmp dx, -16192
   cmove rsi, rcx
   xor eax, eax
   cmp edx, 49344
   cmove rax, rdi
.LBB5_6:
   mov rdx, rsi
   ret
.LBB5_8:
   xor eax, eax
   mov rdx, rsi
   ret
Machine Code Analysis
Iterations:        100
Instructions:      3300
Total Cycles:      1082
Total uOps:        3600

Dispatch Width:    4
uOps Per Cycle:    3.33
IPC:               3.05
Block RThroughput: 9.0


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.33                        mov	rcx, rdx
1      1     0.33                        mov	edx, 3
1      1     0.33                        mov	rax, rcx
2      4     1.00                        mul	rdx
1      1     1.00                        jo	.LBB5_8
1      1     0.33                        mov	rdx, rax
1      1     0.33                        cmp	rax, -10
1      1     1.00                        ja	.LBB5_8
1      1     0.33                        mov	eax, edx
1      1     0.33                        not	eax
1      1     0.33                        and	eax, 3
1      1     0.50                        lea	r8, [rax + rdx]
1      1     0.33                        add	r8, 9
1      0     0.25                        xor	eax, eax
1      1     0.33                        cmp	rsi, r8
1      1     1.00                        jne	.LBB5_6
1      1     0.33                        mov	r9d, edi
1      1     0.33                        and	r9d, 3
1      1     1.00                        jne	.LBB5_6
1      1     0.33                        add	rdx, 9
1      1     0.33                        cmp	r8, rdx
1      1     1.00                        jb	.LBB5_6
1      5     0.50    *                   movzx	edx, word ptr [rdi]
1      1     0.33                        cmp	dx, -16192
2      2     0.67                        cmove	rsi, rcx
1      0     0.25                        xor	eax, eax
1      1     0.33                        cmp	edx, 49344
2      2     0.67                        cmove	rax, rdi
1      1     0.33                        mov	rdx, rsi
1      1     1.00                  U     ret
1      0     0.25                        xor	eax, eax
1      1     0.33                        mov	rdx, rsi
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     10.64  10.65   -     10.71  0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.25   0.73    -     0.02    -      -     mov	rcx, rdx
-      -     0.74   0.03    -     0.23    -      -     mov	edx, 3
-      -     0.60   0.40    -      -      -      -     mov	rax, rcx
-      -     1.00   1.00    -      -      -      -     mul	rdx
-      -      -      -      -     1.00    -      -     jo	.LBB5_8
-      -     0.11   0.89    -      -      -      -     mov	rdx, rax
-      -     0.99   0.01    -      -      -      -     cmp	rax, -10
-      -      -      -      -     1.00    -      -     ja	.LBB5_8
-      -     0.01   0.89    -     0.10    -      -     mov	eax, edx
-      -     0.11   0.89    -      -      -      -     not	eax
-      -     0.01   0.88    -     0.11    -      -     and	eax, 3
-      -     0.01   0.99    -      -      -      -     lea	r8, [rax + rdx]
-      -     0.01   0.99    -      -      -      -     add	r8, 9
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -     0.99    -     0.01    -      -     cmp	rsi, r8
-      -      -      -      -     1.00    -      -     jne	.LBB5_6
-      -     0.42    -      -     0.58    -      -     mov	r9d, edi
-      -     0.53   0.01    -     0.46    -      -     and	r9d, 3
-      -      -      -      -     1.00    -      -     jne	.LBB5_6
-      -     0.99   0.01    -      -      -      -     add	rdx, 9
-      -     0.99   0.01    -      -      -      -     cmp	r8, rdx
-      -      -      -      -     1.00    -      -     jb	.LBB5_6
-      -      -      -      -      -     0.50   0.50   movzx	edx, word ptr [rdi]
-      -     0.45   0.01    -     0.54    -      -     cmp	dx, -16192
-      -     1.00   0.35    -     0.65    -      -     cmove	rsi, rcx
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.75   0.02    -     0.23    -      -     cmp	edx, 49344
-      -     1.00   0.68    -     0.32    -      -     cmove	rax, rdi
-      -     0.12   0.54    -     0.34    -      -     mov	rdx, rsi
-      -      -      -      -     1.00    -      -     ret
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.55   0.33    -     0.12    -      -     mov	rdx, rsi
-      -      -      -      -     1.00    -      -     ret
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);
§ Code Generation

This abstraction is safe and cheap, but does not necessarily have zero runtime cost. The codegen you experience in practice will depend on optimization level, the layout of the destination type, and what the compiler can prove about the source.

The below examples illustrate typical codegen for increasingly complex types:

Unsized
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(2))]
pub struct Packet<Magic> {
   magic_number: Magic,
   mug_size: u8,
   temperature: u8,
   marshmallows: [[u8; 2]],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_dynamic_size.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_prefix_with_elems_dynamic_size(
   source: &[u8],
   count: usize,
) -> Option<&format::CocoPacket> {
   match zerocopy::TryFromBytes::try_ref_from_prefix_with_elems(source, count) {
       Ok((packet, _rest)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_try_ref_from_prefix_with_elems_dynamic_size:
   movabs rax, 9223372036854775805
   cmp rdx, rax
   ja .LBB5_1
   mov rcx, rdx
   xor edx, edx
   mov eax, 0
   test dil, 1
   jne .LBB5_5
   lea rax, [2*rcx + 4]
   cmp rax, rsi
   jbe .LBB5_4
.LBB5_1:
   xor eax, eax
   mov edx, 1
   ret
.LBB5_4:
   movzx esi, word ptr [rdi]
   cmp si, -16192
   mov edx, 2
   cmove rdx, rcx
   xor eax, eax
   cmp esi, 49344
   cmove rax, rdi
.LBB5_5:
   ret
Machine Code Analysis
Iterations:        100
Instructions:      2200
Total Cycles:      674
Total uOps:        2400

Dispatch Width:    4
uOps Per Cycle:    3.56
IPC:               3.26
Block RThroughput: 6.0


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.33                        movabs	rax, 9223372036854775805
1      1     0.33                        cmp	rdx, rax
1      1     1.00                        ja	.LBB5_1
1      1     0.33                        mov	rcx, rdx
1      0     0.25                        xor	edx, edx
1      1     0.33                        mov	eax, 0
1      1     0.33                        test	dil, 1
1      1     1.00                        jne	.LBB5_5
1      1     0.50                        lea	rax, [2*rcx + 4]
1      1     0.33                        cmp	rax, rsi
1      1     1.00                        jbe	.LBB5_4
1      0     0.25                        xor	eax, eax
1      1     0.33                        mov	edx, 1
1      1     1.00                  U     ret
1      5     0.50    *                   movzx	esi, word ptr [rdi]
1      1     0.33                        cmp	si, -16192
1      1     0.33                        mov	edx, 2
2      2     0.67                        cmove	rdx, rcx
1      0     0.25                        xor	eax, eax
1      1     0.33                        cmp	esi, 49344
2      2     0.67                        cmove	rax, rdi
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     6.65   6.66    -     6.69   0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.66   0.33    -     0.01    -      -     movabs	rax, 9223372036854775805
-      -     0.02   0.66    -     0.32    -      -     cmp	rdx, rax
-      -      -      -      -     1.00    -      -     ja	.LBB5_1
-      -     0.66   0.33    -     0.01    -      -     mov	rcx, rdx
-      -      -      -      -      -      -      -     xor	edx, edx
-      -     0.33   0.01    -     0.66    -      -     mov	eax, 0
-      -     0.34   0.65    -     0.01    -      -     test	dil, 1
-      -      -      -      -     1.00    -      -     jne	.LBB5_5
-      -     0.65   0.35    -      -      -      -     lea	rax, [2*rcx + 4]
-      -      -     1.00    -      -      -      -     cmp	rax, rsi
-      -      -      -      -     1.00    -      -     jbe	.LBB5_4
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.34   0.01    -     0.65    -      -     mov	edx, 1
-      -      -      -      -     1.00    -      -     ret
-      -      -      -      -      -     0.50   0.50   movzx	esi, word ptr [rdi]
-      -     0.65   0.34    -     0.01    -      -     cmp	si, -16192
-      -     0.66   0.34    -      -      -      -     mov	edx, 2
-      -     1.00   0.99    -     0.01    -      -     cmove	rdx, rcx
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.34   0.66    -      -      -      -     cmp	esi, 49344
-      -     1.00   0.99    -     0.01    -      -     cmove	rax, rdi
-      -      -      -      -     1.00    -      -     ret
Dynamically Padded
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(4))]
pub struct Packet<Magic> {
   magic_number: Magic,
   milk: u8,
   mug_size: u8,
   temperature: [u8; 5],
   marshmallows: [[u8; 3]],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_dynamic_padding.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_prefix_with_elems_dynamic_padding(
   source: &[u8],
   count: usize,
) -> Option<&format::CocoPacket> {
   match zerocopy::TryFromBytes::try_ref_from_prefix_with_elems(source, count) {
       Ok((packet, _rest)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_try_ref_from_prefix_with_elems_dynamic_padding:
   mov rcx, rdx
   mov edx, 3
   mov rax, rcx
   mul rdx
   jo .LBB5_1
   cmp rax, -10
   ja .LBB5_1
   lea rdx, [rax + 9]
   not eax
   and eax, 3
   add rax, rdx
   jae .LBB5_4
.LBB5_1:
   xor eax, eax
   mov edx, 1
   ret
.LBB5_4:
   mov r8, rax
   xor edx, edx
   mov eax, 0
   test dil, 3
   je .LBB5_5
   ret
.LBB5_5:
   cmp r8, rsi
   ja .LBB5_1
   movzx esi, word ptr [rdi]
   cmp si, -16192
   mov edx, 2
   cmove rdx, rcx
   xor eax, eax
   cmp esi, 49344
   cmove rax, rdi
   ret
Machine Code Analysis
Iterations:        100
Instructions:      3100
Total Cycles:      1008
Total uOps:        3400

Dispatch Width:    4
uOps Per Cycle:    3.37
IPC:               3.08
Block RThroughput: 8.5


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.33                        mov	rcx, rdx
1      1     0.33                        mov	edx, 3
1      1     0.33                        mov	rax, rcx
2      4     1.00                        mul	rdx
1      1     1.00                        jo	.LBB5_1
1      1     0.33                        cmp	rax, -10
1      1     1.00                        ja	.LBB5_1
1      1     0.50                        lea	rdx, [rax + 9]
1      1     0.33                        not	eax
1      1     0.33                        and	eax, 3
1      1     0.33                        add	rax, rdx
1      1     1.00                        jae	.LBB5_4
1      0     0.25                        xor	eax, eax
1      1     0.33                        mov	edx, 1
1      1     1.00                  U     ret
1      1     0.33                        mov	r8, rax
1      0     0.25                        xor	edx, edx
1      1     0.33                        mov	eax, 0
1      1     0.33                        test	dil, 3
1      1     1.00                        je	.LBB5_5
1      1     1.00                  U     ret
1      1     0.33                        cmp	r8, rsi
1      1     1.00                        ja	.LBB5_1
1      5     0.50    *                   movzx	esi, word ptr [rdi]
1      1     0.33                        cmp	si, -16192
1      1     0.33                        mov	edx, 2
2      2     0.67                        cmove	rdx, rcx
1      0     0.25                        xor	eax, eax
1      1     0.33                        cmp	esi, 49344
2      2     0.67                        cmove	rax, rdi
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     9.98   9.99    -     10.03  0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.49   0.50    -     0.01    -      -     mov	rcx, rdx
-      -     0.01   0.99    -      -      -      -     mov	edx, 3
-      -     0.99   0.01    -      -      -      -     mov	rax, rcx
-      -     1.00   1.00    -      -      -      -     mul	rdx
-      -      -      -      -     1.00    -      -     jo	.LBB5_1
-      -     1.00    -      -      -      -      -     cmp	rax, -10
-      -      -      -      -     1.00    -      -     ja	.LBB5_1
-      -      -     1.00    -      -      -      -     lea	rdx, [rax + 9]
-      -     1.00    -      -      -      -      -     not	eax
-      -     0.99   0.01    -      -      -      -     and	eax, 3
-      -     0.99   0.01    -      -      -      -     add	rax, rdx
-      -      -      -      -     1.00    -      -     jae	.LBB5_4
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -     0.98    -     0.02    -      -     mov	edx, 1
-      -      -      -      -     1.00    -      -     ret
-      -     0.50   0.50    -      -      -      -     mov	r8, rax
-      -      -      -      -      -      -      -     xor	edx, edx
-      -     0.02   0.49    -     0.49    -      -     mov	eax, 0
-      -      -     0.49    -     0.51    -      -     test	dil, 3
-      -      -      -      -     1.00    -      -     je	.LBB5_5
-      -      -      -      -     1.00    -      -     ret
-      -     0.98   0.02    -      -      -      -     cmp	r8, rsi
-      -      -      -      -     1.00    -      -     ja	.LBB5_1
-      -      -      -      -      -     0.50   0.50   movzx	esi, word ptr [rdi]
-      -     0.02   0.98    -      -      -      -     cmp	si, -16192
-      -     0.98   0.02    -      -      -      -     mov	edx, 2
-      -     0.50   1.00    -     0.50    -      -     cmove	rdx, rcx
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.01   0.99    -      -      -      -     cmp	esi, 49344
-      -     0.50   1.00    -     0.50    -      -     cmove	rax, rdi
-      -      -      -      -     1.00    -      -     ret
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);
§ Code Generation

This abstraction is safe and cheap, but does not necessarily have zero runtime cost. The codegen you experience in practice will depend on optimization level, the layout of the destination type, and what the compiler can prove about the source.

The below examples illustrate typical codegen for increasingly complex types:

Unsized
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(2))]
pub struct Packet<Magic> {
   magic_number: Magic,
   mug_size: u8,
   temperature: u8,
   marshmallows: [[u8; 2]],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_dynamic_size.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_suffix_with_elems_dynamic_size(
   source: &[u8],
   count: usize,
) -> Option<&format::CocoPacket> {
   match zerocopy::TryFromBytes::try_ref_from_suffix_with_elems(source, count) {
       Ok((_rest, packet)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_try_ref_from_suffix_with_elems_dynamic_size:
   movabs rax, 9223372036854775805
   cmp rdx, rax
   ja .LBB5_1
   lea r8d, [rsi + rdi]
   xor ecx, ecx
   mov eax, 0
   test r8b, 1
   jne .LBB5_5
   lea rax, [2*rdx + 4]
   sub rsi, rax
   jae .LBB5_4
.LBB5_1:
   xor eax, eax
   mov edx, 1
   ret
.LBB5_4:
   lea r8, [rdi + rsi]
   movzx esi, word ptr [rdi + rsi]
   cmp si, -16192
   mov ecx, 2
   cmove rcx, rdx
   xor eax, eax
   cmp esi, 49344
   cmove rax, r8
.LBB5_5:
   mov rdx, rcx
   ret
Machine Code Analysis
Iterations:        100
Instructions:      2400
Total Cycles:      1107
Total uOps:        2600

Dispatch Width:    4
uOps Per Cycle:    2.35
IPC:               2.17
Block RThroughput: 6.5


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.33                        movabs	rax, 9223372036854775805
1      1     0.33                        cmp	rdx, rax
1      1     1.00                        ja	.LBB5_1
1      1     0.50                        lea	r8d, [rsi + rdi]
1      0     0.25                        xor	ecx, ecx
1      1     0.33                        mov	eax, 0
1      1     0.33                        test	r8b, 1
1      1     1.00                        jne	.LBB5_5
1      1     0.50                        lea	rax, [2*rdx + 4]
1      1     0.33                        sub	rsi, rax
1      1     1.00                        jae	.LBB5_4
1      0     0.25                        xor	eax, eax
1      1     0.33                        mov	edx, 1
1      1     1.00                  U     ret
1      1     0.50                        lea	r8, [rdi + rsi]
1      5     0.50    *                   movzx	esi, word ptr [rdi + rsi]
1      1     0.33                        cmp	si, -16192
1      1     0.33                        mov	ecx, 2
2      2     0.67                        cmove	rcx, rdx
1      0     0.25                        xor	eax, eax
1      1     0.33                        cmp	esi, 49344
2      2     0.67                        cmove	rax, r8
1      1     0.33                        mov	rdx, rcx
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     6.99   7.00    -     8.01   0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.02   0.95    -     0.03    -      -     movabs	rax, 9223372036854775805
-      -     0.93   0.04    -     0.03    -      -     cmp	rdx, rax
-      -      -      -      -     1.00    -      -     ja	.LBB5_1
-      -     0.96   0.04    -      -      -      -     lea	r8d, [rsi + rdi]
-      -      -      -      -      -      -      -     xor	ecx, ecx
-      -     0.95   0.02    -     0.03    -      -     mov	eax, 0
-      -     0.95   0.05    -      -      -      -     test	r8b, 1
-      -      -      -      -     1.00    -      -     jne	.LBB5_5
-      -     0.06   0.94    -      -      -      -     lea	rax, [2*rdx + 4]
-      -     0.93   0.07    -      -      -      -     sub	rsi, rax
-      -      -      -      -     1.00    -      -     jae	.LBB5_4
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.03   0.95    -     0.02    -      -     mov	edx, 1
-      -      -      -      -     1.00    -      -     ret
-      -     0.97   0.03    -      -      -      -     lea	r8, [rdi + rsi]
-      -      -      -      -      -     0.50   0.50   movzx	esi, word ptr [rdi + rsi]
-      -     0.03   0.97    -      -      -      -     cmp	si, -16192
-      -     0.05   0.94    -     0.01    -      -     mov	ecx, 2
-      -     0.06   0.98    -     0.96    -      -     cmove	rcx, rdx
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.97   0.03    -      -      -      -     cmp	esi, 49344
-      -     0.06   0.96    -     0.98    -      -     cmove	rax, r8
-      -     0.02   0.03    -     0.95    -      -     mov	rdx, rcx
-      -      -      -      -     1.00    -      -     ret
Dynamically Padded
Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(4))]
pub struct Packet<Magic> {
   magic_number: Magic,
   milk: u8,
   mug_size: u8,
   temperature: [u8; 5],
   marshmallows: [[u8; 3]],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_dynamic_padding.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_ref_from_suffix_with_elems_dynamic_padding(
   source: &[u8],
   count: usize,
) -> Option<&format::CocoPacket> {
   match zerocopy::TryFromBytes::try_ref_from_suffix_with_elems(source, count) {
       Ok((_rest, packet)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_try_ref_from_suffix_with_elems_dynamic_padding:
   mov rcx, rdx
   mov edx, 3
   mov rax, rcx
   mul rdx
   jo .LBB5_1
   cmp rax, -10
   ja .LBB5_1
   lea rdx, [rax + 9]
   not eax
   and eax, 3
   add rax, rdx
   jae .LBB5_4
.LBB5_1:
   xor r8d, r8d
   mov edx, 1
   mov rax, r8
   ret
.LBB5_4:
   lea r9d, [rsi + rdi]
   xor edx, edx
   mov r8d, 0
   test r9b, 3
   je .LBB5_5
   mov rax, r8
   ret
.LBB5_5:
   sub rsi, rax
   jb .LBB5_1
   lea rax, [rdi + rsi]
   movzx esi, word ptr [rdi + rsi]
   cmp si, -16192
   mov edx, 2
   cmove rdx, rcx
   xor r8d, r8d
   cmp esi, 49344
   cmove r8, rax
   mov rax, r8
   ret
Machine Code Analysis
Iterations:        100
Instructions:      3500
Total Cycles:      1144
Total uOps:        3800

Dispatch Width:    4
uOps Per Cycle:    3.32
IPC:               3.06
Block RThroughput: 9.5


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.33                        mov	rcx, rdx
1      1     0.33                        mov	edx, 3
1      1     0.33                        mov	rax, rcx
2      4     1.00                        mul	rdx
1      1     1.00                        jo	.LBB5_1
1      1     0.33                        cmp	rax, -10
1      1     1.00                        ja	.LBB5_1
1      1     0.50                        lea	rdx, [rax + 9]
1      1     0.33                        not	eax
1      1     0.33                        and	eax, 3
1      1     0.33                        add	rax, rdx
1      1     1.00                        jae	.LBB5_4
1      0     0.25                        xor	r8d, r8d
1      1     0.33                        mov	edx, 1
1      1     0.33                        mov	rax, r8
1      1     1.00                  U     ret
1      1     0.50                        lea	r9d, [rsi + rdi]
1      0     0.25                        xor	edx, edx
1      1     0.33                        mov	r8d, 0
1      1     0.33                        test	r9b, 3
1      1     1.00                        je	.LBB5_5
1      1     0.33                        mov	rax, r8
1      1     1.00                  U     ret
1      1     0.33                        sub	rsi, rax
1      1     1.00                        jb	.LBB5_1
1      1     0.50                        lea	rax, [rdi + rsi]
1      5     0.50    *                   movzx	esi, word ptr [rdi + rsi]
1      1     0.33                        cmp	si, -16192
1      1     0.33                        mov	edx, 2
2      2     0.67                        cmove	rdx, rcx
1      0     0.25                        xor	r8d, r8d
1      1     0.33                        cmp	esi, 49344
2      2     0.67                        cmove	r8, rax
1      1     0.33                        mov	rax, r8
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     11.32  11.32   -     11.36  0.50   0.50   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.32   0.67    -     0.01    -      -     mov	rcx, rdx
-      -     0.66   0.18    -     0.16    -      -     mov	edx, 3
-      -     1.00    -      -      -      -      -     mov	rax, rcx
-      -     1.00   1.00    -      -      -      -     mul	rdx
-      -      -      -      -     1.00    -      -     jo	.LBB5_1
-      -     0.01   0.99    -      -      -      -     cmp	rax, -10
-      -      -      -      -     1.00    -      -     ja	.LBB5_1
-      -     0.99   0.01    -      -      -      -     lea	rdx, [rax + 9]
-      -     0.01   0.99    -      -      -      -     not	eax
-      -     0.02   0.98    -      -      -      -     and	eax, 3
-      -     0.02   0.98    -      -      -      -     add	rax, rdx
-      -      -      -      -     1.00    -      -     jae	.LBB5_4
-      -      -      -      -      -      -      -     xor	r8d, r8d
-      -     0.66   0.01    -     0.33    -      -     mov	edx, 1
-      -     0.50    -      -     0.50    -      -     mov	rax, r8
-      -      -      -      -     1.00    -      -     ret
-      -     0.99   0.01    -      -      -      -     lea	r9d, [rsi + rdi]
-      -      -      -      -      -      -      -     xor	edx, edx
-      -     0.50   0.32    -     0.18    -      -     mov	r8d, 0
-      -     0.16   0.17    -     0.67    -      -     test	r9b, 3
-      -      -      -      -     1.00    -      -     je	.LBB5_5
-      -     0.33   0.33    -     0.34    -      -     mov	rax, r8
-      -      -      -      -     1.00    -      -     ret
-      -      -     0.51    -     0.49    -      -     sub	rsi, rax
-      -      -      -      -     1.00    -      -     jb	.LBB5_1
-      -     0.16   0.84    -      -      -      -     lea	rax, [rdi + rsi]
-      -      -      -      -      -     0.50   0.50   movzx	esi, word ptr [rdi + rsi]
-      -     0.02   0.98    -      -      -      -     cmp	si, -16192
-      -     1.00    -      -      -      -      -     mov	edx, 2
-      -     0.99   0.84    -     0.17    -      -     cmove	rdx, rcx
-      -      -      -      -      -      -      -     xor	r8d, r8d
-      -     0.98    -      -     0.02    -      -     cmp	esi, 49344
-      -     0.99   0.52    -     0.49    -      -     cmove	r8, rax
-      -     0.01   0.99    -      -      -      -     mov	rax, r8
-      -      -      -      -     1.00    -      -     ret
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> + IntoBytes,

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, IntoBytes, KnownLayout)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

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

#[derive(TryFromBytes, IntoBytes, KnownLayout)]
#[repr(C, packed)]
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, IntoBytes, KnownLayout)]
#[repr(C, packed)]
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);
§ Code Generation

See TryFromBytes::try_ref_from_bytes_with_elems.

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> + IntoBytes,

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, IntoBytes, KnownLayout)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

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

#[derive(TryFromBytes, IntoBytes, KnownLayout)]
#[repr(C, packed)]
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, IntoBytes, KnownLayout)]
#[repr(C, packed)]
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);
§ Code Generation

See TryFromBytes::try_ref_from_prefix_with_elems.

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> + IntoBytes,

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, IntoBytes, KnownLayout)]
#[repr(u8)]
enum C0 { xC0 = 0xC0 }

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

#[derive(TryFromBytes, IntoBytes, KnownLayout)]
#[repr(C, packed)]
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, IntoBytes, KnownLayout)]
#[repr(C, packed)]
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);
§ Code Generation

See TryFromBytes::try_ref_from_suffix_with_elems.

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());
§Performance Considerations

In this version of zerocopy, this method reads the source into a well-aligned stack allocation and then validates that the allocation is a valid Self. This ensures that validation can be performed using aligned reads (which carry a performance advantage over unaligned reads on many platforms) at the cost of an unconditional copy.

§ Code Generation

This abstraction is safe and cheap, but does not necessarily have zero runtime cost. The codegen you experience in practice will depend on optimization level, the layout of the destination type, and what the compiler can prove about the source.

Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(2))]
pub struct Packet<Magic> {
   magic_number: Magic,
   mug_size: u8,
   temperature: u8,
   marshmallows: [u8; 2],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_static_size.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_read_from_bytes_static_size(source: &[u8]) -> Option<format::CocoPacket> {
   zerocopy::TryFromBytes::try_read_from_bytes(source).ok()
}
Assembly
bench_try_read_from_bytes_static_size:
   mov ax, -16191
   cmp rsi, 6
   jne .LBB5_1
   mov ecx, dword ptr [rdi]
   movzx edx, cx
   cmp edx, 49344
   jne .LBB5_4
   movzx eax, word ptr [rdi + 4]
   shl rax, 32
   or rcx, rax
   shr rcx, 16
   mov ax, -16192
.LBB5_4:
   shl rcx, 16
   movzx eax, ax
   or rax, rcx
   ret
.LBB5_1:
   shl rcx, 16
   movzx eax, ax
   or rax, rcx
   ret
Machine Code Analysis
Iterations:        100
Instructions:      2000
Total Cycles:      608
Total uOps:        2000

Dispatch Width:    4
uOps Per Cycle:    3.29
IPC:               3.29
Block RThroughput: 5.0


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.33                        mov	ax, -16191
1      1     0.33                        cmp	rsi, 6
1      1     1.00                        jne	.LBB5_1
1      5     0.50    *                   mov	ecx, dword ptr [rdi]
1      1     0.33                        movzx	edx, cx
1      1     0.33                        cmp	edx, 49344
1      1     1.00                        jne	.LBB5_4
1      5     0.50    *                   movzx	eax, word ptr [rdi + 4]
1      1     0.50                        shl	rax, 32
1      1     0.33                        or	rcx, rax
1      1     0.50                        shr	rcx, 16
1      1     0.33                        mov	ax, -16192
1      1     0.50                        shl	rcx, 16
1      1     0.33                        movzx	eax, ax
1      1     0.33                        or	rax, rcx
1      1     1.00                  U     ret
1      1     0.50                        shl	rcx, 16
1      1     0.33                        movzx	eax, ax
1      1     0.33                        or	rax, rcx
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     5.99   5.99    -     6.02   1.00   1.00   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -      -     0.99    -     0.01    -      -     mov	ax, -16191
-      -      -     0.01    -     0.99    -      -     cmp	rsi, 6
-      -      -      -      -     1.00    -      -     jne	.LBB5_1
-      -      -      -      -      -      -     1.00   mov	ecx, dword ptr [rdi]
-      -     0.98    -      -     0.02    -      -     movzx	edx, cx
-      -     0.99   0.01    -      -      -      -     cmp	edx, 49344
-      -      -      -      -     1.00    -      -     jne	.LBB5_4
-      -      -      -      -      -     1.00    -     movzx	eax, word ptr [rdi + 4]
-      -     0.01    -      -     0.99    -      -     shl	rax, 32
-      -     0.02   0.98    -      -      -      -     or	rcx, rax
-      -     1.00    -      -      -      -      -     shr	rcx, 16
-      -     0.99   0.01    -      -      -      -     mov	ax, -16192
-      -     1.00    -      -      -      -      -     shl	rcx, 16
-      -      -     1.00    -      -      -      -     movzx	eax, ax
-      -      -     1.00    -      -      -      -     or	rax, rcx
-      -      -      -      -     1.00    -      -     ret
-      -     1.00    -      -      -      -      -     shl	rcx, 16
-      -      -     1.00    -      -      -      -     movzx	eax, ax
-      -      -     0.99    -     0.01    -      -     or	rax, rcx
-      -      -      -      -     1.00    -      -     ret
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());
§Performance Considerations

In this version of zerocopy, this method reads the source into a well-aligned stack allocation and then validates that the allocation is a valid Self. This ensures that validation can be performed using aligned reads (which carry a performance advantage over unaligned reads on many platforms) at the cost of an unconditional copy.

§ Code Generation

This abstraction is safe and cheap, but does not necessarily have zero runtime cost. The codegen you experience in practice will depend on optimization level, the layout of the destination type, and what the compiler can prove about the source.

Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(2))]
pub struct Packet<Magic> {
   magic_number: Magic,
   mug_size: u8,
   temperature: u8,
   marshmallows: [u8; 2],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_static_size.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_read_from_prefix_static_size(source: &[u8]) -> Option<format::CocoPacket> {
   match zerocopy::TryFromBytes::try_read_from_prefix(source) {
       Ok((packet, _rest)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_try_read_from_prefix_static_size:
   mov eax, 49345
   cmp rsi, 6
   jb .LBB5_2
   mov eax, dword ptr [rdi]
   movzx ecx, word ptr [rdi + 4]
   shl rcx, 32
   or rcx, rax
   movzx eax, cx
   and rcx, -65536
   or rcx, 49344
   cmp eax, 49344
   mov eax, 49345
   cmove rax, rcx
.LBB5_2:
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1400
Total Cycles:      442
Total uOps:        1500

Dispatch Width:    4
uOps Per Cycle:    3.39
IPC:               3.17
Block RThroughput: 3.8


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.33                        mov	eax, 49345
1      1     0.33                        cmp	rsi, 6
1      1     1.00                        jb	.LBB5_2
1      5     0.50    *                   mov	eax, dword ptr [rdi]
1      5     0.50    *                   movzx	ecx, word ptr [rdi + 4]
1      1     0.50                        shl	rcx, 32
1      1     0.33                        or	rcx, rax
1      1     0.33                        movzx	eax, cx
1      1     0.33                        and	rcx, -65536
1      1     0.33                        or	rcx, 49344
1      1     0.33                        cmp	eax, 49344
1      1     0.33                        mov	eax, 49345
2      2     0.67                        cmove	rax, rcx
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     4.33   4.33    -     4.34   1.00   1.00   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.65   0.01    -     0.34    -      -     mov	eax, 49345
-      -     0.01   0.33    -     0.66    -      -     cmp	rsi, 6
-      -      -      -      -     1.00    -      -     jb	.LBB5_2
-      -      -      -      -      -      -     1.00   mov	eax, dword ptr [rdi]
-      -      -      -      -      -     1.00    -     movzx	ecx, word ptr [rdi + 4]
-      -     0.65    -      -     0.35    -      -     shl	rcx, 32
-      -      -     0.67    -     0.33    -      -     or	rcx, rax
-      -     0.01   0.99    -      -      -      -     movzx	eax, cx
-      -     0.99   0.01    -      -      -      -     and	rcx, -65536
-      -     0.01   0.99    -      -      -      -     or	rcx, 49344
-      -     0.99   0.01    -      -      -      -     cmp	eax, 49344
-      -     0.02   0.33    -     0.65    -      -     mov	eax, 49345
-      -     1.00   0.99    -     0.01    -      -     cmove	rax, rcx
-      -      -      -      -     1.00    -      -     ret
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());
§Performance Considerations

In this version of zerocopy, this method reads the source into a well-aligned stack allocation and then validates that the allocation is a valid Self. This ensures that validation can be performed using aligned reads (which carry a performance advantage over unaligned reads on many platforms) at the cost of an unconditional copy.

§ Code Generation

This abstraction is safe and cheap, but does not necessarily have zero runtime cost. The codegen you experience in practice will depend on optimization level, the layout of the destination type, and what the compiler can prove about the source.

Format
use zerocopy_derive::*;

// The only valid value of this type are the bytes `0xC0C0`.
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
pub enum C0C0 {
   _XC0C0 = 0xC0C0,
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(2))]
pub struct Packet<Magic> {
   magic_number: Magic,
   mug_size: u8,
   temperature: u8,
   marshmallows: [u8; 2],
}

/// A packet begining with the magic number `0xC0C0`.
pub type CocoPacket = Packet<C0C0>;

/// A packet beginning with any two initialized bytes.
pub type LocoPacket = Packet<[u8; 2]>;
Benchmark
#[path = "formats/coco_static_size.rs"]
mod format;

#[unsafe(no_mangle)]
fn bench_try_read_from_suffix_static_size(source: &[u8]) -> Option<format::CocoPacket> {
   match zerocopy::TryFromBytes::try_read_from_suffix(source) {
       Ok((_rest, packet)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_try_read_from_suffix_static_size:
   mov eax, 49345
   cmp rsi, 6
   jb .LBB5_2
   mov eax, dword ptr [rdi + rsi - 6]
   movzx ecx, word ptr [rdi + rsi - 2]
   shl rcx, 32
   or rcx, rax
   movzx edx, cx
   xor eax, eax
   cmp edx, 49344
   cmovne rcx, rsi
   sete al
   and rcx, -65536
   xor rax, 49345
   or rax, rcx
.LBB5_2:
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1600
Total Cycles:      478
Total uOps:        1700

Dispatch Width:    4
uOps Per Cycle:    3.56
IPC:               3.35
Block RThroughput: 4.3


Instruction Info:
[1]: #uOps
[2]: Latency
[3]: RThroughput
[4]: MayLoad
[5]: MayStore
[6]: HasSideEffects (U)

[1]    [2]    [3]    [4]    [5]    [6]    Instructions:
1      1     0.33                        mov	eax, 49345
1      1     0.33                        cmp	rsi, 6
1      1     1.00                        jb	.LBB5_2
1      5     0.50    *                   mov	eax, dword ptr [rdi + rsi - 6]
1      5     0.50    *                   movzx	ecx, word ptr [rdi + rsi - 2]
1      1     0.50                        shl	rcx, 32
1      1     0.33                        or	rcx, rax
1      1     0.33                        movzx	edx, cx
1      0     0.25                        xor	eax, eax
1      1     0.33                        cmp	edx, 49344
2      2     0.67                        cmovne	rcx, rsi
1      1     0.50                        sete	al
1      1     0.33                        and	rcx, -65536
1      1     0.33                        xor	rax, 49345
1      1     0.33                        or	rax, rcx
1      1     1.00                  U     ret


Resources:
[0]   - SBDivider
[1]   - SBFPDivider
[2]   - SBPort0
[3]   - SBPort1
[4]   - SBPort4
[5]   - SBPort5
[6.0] - SBPort23
[6.1] - SBPort23


Resource pressure per iteration:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  
-      -     4.66   4.66    -     4.68   1.00   1.00   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.32   0.01    -     0.67    -      -     mov	eax, 49345
-      -     0.62   0.02    -     0.36    -      -     cmp	rsi, 6
-      -      -      -      -     1.00    -      -     jb	.LBB5_2
-      -      -      -      -      -      -     1.00   mov	eax, dword ptr [rdi + rsi - 6]
-      -      -      -      -      -     1.00    -     movzx	ecx, word ptr [rdi + rsi - 2]
-      -     0.37    -      -     0.63    -      -     shl	rcx, 32
-      -     0.99   0.01    -      -      -      -     or	rcx, rax
-      -     1.00    -      -      -      -      -     movzx	edx, cx
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.35   0.64    -     0.01    -      -     cmp	edx, 49344
-      -     1.00   1.00    -      -      -      -     cmovne	rcx, rsi
-      -      -      -      -     1.00    -      -     sete	al
-      -     0.01   0.99    -      -      -      -     and	rcx, -65536
-      -      -     1.00    -      -      -      -     xor	rax, 49345
-      -      -     0.99    -     0.01    -      -     or	rax, rcx
-      -      -      -      -     1.00    -      -     ret

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 __m128

Source§

impl TryFromBytes for __m128d

Source§

impl TryFromBytes for __m128i

Source§

impl TryFromBytes for __m256

Source§

impl TryFromBytes for __m256d

Source§

impl TryFromBytes for __m256i

Source§

impl TryFromBytes for __m512

Source§

impl TryFromBytes for __m512bh

Source§

impl TryFromBytes for __m512d

Source§

impl TryFromBytes for __m512i

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<A, B, C, D, E, F, G, H, I, J, K, L, M> TryFromBytes for Option<unsafe 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<unsafe extern "C" fn(A, B, C, D, E, F, G, H, I, J, K, L) -> M>

Source§

impl<A: TryFromBytes> TryFromBytes for (A,)

Source§

impl<A: TryFromBytes, B: TryFromBytes> TryFromBytes for (A, B)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes> TryFromBytes for (A, B, C)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes> TryFromBytes for (A, B, C, D)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes> TryFromBytes for (A, B, C, D, E)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes> TryFromBytes for (A, B, C, D, E, F)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes, J: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I, J)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes, J: TryFromBytes, K: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I, J, K)

Source§

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

Source§

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

Source§

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

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes, J: TryFromBytes, K: TryFromBytes, L: TryFromBytes, M: TryFromBytes, N: TryFromBytes, O: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes, J: TryFromBytes, K: TryFromBytes, L: TryFromBytes, M: TryFromBytes, N: TryFromBytes, O: TryFromBytes, P: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes, J: TryFromBytes, K: TryFromBytes, L: TryFromBytes, M: TryFromBytes, N: TryFromBytes, O: TryFromBytes, P: TryFromBytes, Q: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes, J: TryFromBytes, K: TryFromBytes, L: TryFromBytes, M: TryFromBytes, N: TryFromBytes, O: TryFromBytes, P: TryFromBytes, Q: TryFromBytes, R: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes, J: TryFromBytes, K: TryFromBytes, L: TryFromBytes, M: TryFromBytes, N: TryFromBytes, O: TryFromBytes, P: TryFromBytes, Q: TryFromBytes, R: TryFromBytes, S: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes, J: TryFromBytes, K: TryFromBytes, L: TryFromBytes, M: TryFromBytes, N: TryFromBytes, O: TryFromBytes, P: TryFromBytes, Q: TryFromBytes, R: TryFromBytes, S: TryFromBytes, T: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes, J: TryFromBytes, K: TryFromBytes, L: TryFromBytes, M: TryFromBytes, N: TryFromBytes, O: TryFromBytes, P: TryFromBytes, Q: TryFromBytes, R: TryFromBytes, S: TryFromBytes, T: TryFromBytes, U: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes, J: TryFromBytes, K: TryFromBytes, L: TryFromBytes, M: TryFromBytes, N: TryFromBytes, O: TryFromBytes, P: TryFromBytes, Q: TryFromBytes, R: TryFromBytes, S: TryFromBytes, T: TryFromBytes, U: TryFromBytes, V: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes, J: TryFromBytes, K: TryFromBytes, L: TryFromBytes, M: TryFromBytes, N: TryFromBytes, O: TryFromBytes, P: TryFromBytes, Q: TryFromBytes, R: TryFromBytes, S: TryFromBytes, T: TryFromBytes, U: TryFromBytes, V: TryFromBytes, W: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes, J: TryFromBytes, K: TryFromBytes, L: TryFromBytes, M: TryFromBytes, N: TryFromBytes, O: TryFromBytes, P: TryFromBytes, Q: TryFromBytes, R: TryFromBytes, S: TryFromBytes, T: TryFromBytes, U: TryFromBytes, V: TryFromBytes, W: TryFromBytes, X: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes, J: TryFromBytes, K: TryFromBytes, L: TryFromBytes, M: TryFromBytes, N: TryFromBytes, O: TryFromBytes, P: TryFromBytes, Q: TryFromBytes, R: TryFromBytes, S: TryFromBytes, T: TryFromBytes, U: TryFromBytes, V: TryFromBytes, W: TryFromBytes, X: TryFromBytes, Y: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y)

Source§

impl<A: TryFromBytes, B: TryFromBytes, C: TryFromBytes, D: TryFromBytes, E: TryFromBytes, F: TryFromBytes, G: TryFromBytes, H: TryFromBytes, I: TryFromBytes, J: TryFromBytes, K: TryFromBytes, L: TryFromBytes, M: TryFromBytes, N: TryFromBytes, O: TryFromBytes, P: TryFromBytes, Q: TryFromBytes, R: TryFromBytes, S: TryFromBytes, T: TryFromBytes, U: TryFromBytes, V: TryFromBytes, W: TryFromBytes, X: TryFromBytes, Y: TryFromBytes, Z: TryFromBytes> TryFromBytes for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z)

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<B, C, D, E, F, G, H, I, J, K, L, M> TryFromBytes for Option<unsafe 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<unsafe 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<C, D, E, F, G, H, I, J, K, L, M> TryFromBytes for Option<unsafe 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<unsafe 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<D, E, F, G, H, I, J, K, L, M> TryFromBytes for Option<unsafe 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<unsafe 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<E, F, G, H, I, J, K, L, M> TryFromBytes for Option<unsafe fn(E, F, G, H, I, J, K, L) -> M>

Source§

impl<E, F, G, H, I, J, K, L, M> TryFromBytes for Option<unsafe 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<F, G, H, I, J, K, L, M> TryFromBytes for Option<unsafe fn(F, G, H, I, J, K, L) -> M>

Source§

impl<F, G, H, I, J, K, L, M> TryFromBytes for Option<unsafe 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<G, H, I, J, K, L, M> TryFromBytes for Option<unsafe fn(G, H, I, J, K, L) -> M>

Source§

impl<G, H, I, J, K, L, M> TryFromBytes for Option<unsafe 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<H, I, J, K, L, M> TryFromBytes for Option<unsafe fn(H, I, J, K, L) -> M>

Source§

impl<H, I, J, K, L, M> TryFromBytes for Option<unsafe 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<I, J, K, L, M> TryFromBytes for Option<unsafe fn(I, J, K, L) -> M>

Source§

impl<I, J, K, L, M> TryFromBytes for Option<unsafe 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<J, K, L, M> TryFromBytes for Option<unsafe fn(J, K, L) -> M>

Source§

impl<J, K, L, M> TryFromBytes for Option<unsafe 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<K, L, M> TryFromBytes for Option<unsafe fn(K, L) -> M>

Source§

impl<K, L, M> TryFromBytes for Option<unsafe 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<L, M> TryFromBytes for Option<unsafe fn(L) -> M>

Source§

impl<L, M> TryFromBytes for Option<unsafe 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<M> TryFromBytes for Option<unsafe fn() -> M>

Source§

impl<M> TryFromBytes for Option<unsafe 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 CoreMaybeUninit<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 Cell<T>

Source§

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

Source§

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

Implementors§