FromBytes

Trait FromBytes 

Source
pub unsafe trait FromBytes: FromZeros {
Show 15 methods // Provided methods fn ref_from_bytes(source: &[u8]) -> Result<&Self, CastError<&[u8], Self>> where Self: KnownLayout + Immutable { ... } fn ref_from_prefix( source: &[u8], ) -> Result<(&Self, &[u8]), CastError<&[u8], Self>> where Self: KnownLayout + Immutable { ... } fn ref_from_suffix( source: &[u8], ) -> Result<(&[u8], &Self), CastError<&[u8], Self>> where Self: Immutable + KnownLayout { ... } fn mut_from_bytes( source: &mut [u8], ) -> Result<&mut Self, CastError<&mut [u8], Self>> where Self: IntoBytes + KnownLayout { ... } fn mut_from_prefix( source: &mut [u8], ) -> Result<(&mut Self, &mut [u8]), CastError<&mut [u8], Self>> where Self: IntoBytes + KnownLayout { ... } fn mut_from_suffix( source: &mut [u8], ) -> Result<(&mut [u8], &mut Self), CastError<&mut [u8], Self>> where Self: IntoBytes + KnownLayout { ... } fn ref_from_bytes_with_elems( source: &[u8], count: usize, ) -> Result<&Self, CastError<&[u8], Self>> where Self: KnownLayout<PointerMetadata = usize> + Immutable { ... } fn ref_from_prefix_with_elems( source: &[u8], count: usize, ) -> Result<(&Self, &[u8]), CastError<&[u8], Self>> where Self: KnownLayout<PointerMetadata = usize> + Immutable { ... } fn ref_from_suffix_with_elems( source: &[u8], count: usize, ) -> Result<(&[u8], &Self), CastError<&[u8], Self>> where Self: KnownLayout<PointerMetadata = usize> + Immutable { ... } fn mut_from_bytes_with_elems( source: &mut [u8], count: usize, ) -> Result<&mut Self, CastError<&mut [u8], Self>> where Self: IntoBytes + KnownLayout<PointerMetadata = usize> + Immutable { ... } fn mut_from_prefix_with_elems( source: &mut [u8], count: usize, ) -> Result<(&mut Self, &mut [u8]), CastError<&mut [u8], Self>> where Self: IntoBytes + KnownLayout<PointerMetadata = usize> { ... } fn mut_from_suffix_with_elems( source: &mut [u8], count: usize, ) -> Result<(&mut [u8], &mut Self), CastError<&mut [u8], Self>> where Self: IntoBytes + KnownLayout<PointerMetadata = usize> { ... } fn read_from_bytes(source: &[u8]) -> Result<Self, SizeError<&[u8], Self>> where Self: Sized { ... } fn read_from_prefix( source: &[u8], ) -> Result<(Self, &[u8]), SizeError<&[u8], Self>> where Self: Sized { ... } fn read_from_suffix( source: &[u8], ) -> Result<(&[u8], Self), SizeError<&[u8], Self>> where Self: Sized { ... }
}
Expand description

Types for which any bit pattern is valid.

Any memory region of the appropriate length which contains initialized bytes can be viewed as any FromBytes type with no runtime overhead. This is useful for efficiently parsing bytes as structured data.

§Warning: Padding bytes

Note that, when a value is moved or copied, only the non-padding bytes of that value are guaranteed to be preserved. It is unsound to assume that values written to padding bytes are preserved after a move or copy. For example, the following is unsound:

use core::mem::{size_of, transmute};
use zerocopy::FromZeros;

// Assume `Foo` is a type with padding bytes.
#[derive(FromZeros, Default)]
struct Foo {
    ...
}

let mut foo: Foo = Foo::default();
FromZeros::zero(&mut foo);
// UNSOUND: Although `FromZeros::zero` writes zeros to all bytes of `foo`,
// those writes are not guaranteed to be preserved in padding bytes when
// `foo` is moved, so this may expose padding bytes as `u8`s.
let foo_bytes: [u8; size_of::<Foo>()] = unsafe { transmute(foo) };

§Implementation

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

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

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

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

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

§Safety

This section describes what is required in order for T: FromBytes, and what unsafe code may assume of such types. If you don’t plan on implementing FromBytes manually, and you don’t plan on writing unsafe code that operates on FromBytes types, then you don’t need to read this section.

If T: FromBytes, then unsafe code may assume that it is sound to produce a T whose bytes are initialized to any sequence of valid u8s (in other words, any byte value which is not uninitialized). If a type is marked as FromBytes which violates this contract, it may cause undefined behavior.

#[derive(FromBytes)] only permits types which satisfy these requirements.

Provided Methods§

Source

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

Interprets the given source as a &Self.

This method attempts to return a reference to source interpreted as a Self. If the length of source is not a valid size of Self, or if source is not appropriately aligned, 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(FromBytes, Immutable, KnownLayout)]
#[repr(C)]
struct ZSTy {
    leading_sized: u16,
    trailing_dst: [()],
}

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

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct PacketHeader {
    src_port: [u8; 2],
    dst_port: [u8; 2],
    length: [u8; 2],
    checksum: [u8; 2],
}

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

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

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

assert_eq!(packet.header.src_port, [0, 1]);
assert_eq!(packet.header.dst_port, [2, 3]);
assert_eq!(packet.header.length, [4, 5]);
assert_eq!(packet.header.checksum, [6, 7]);
assert_eq!(packet.body, [8, 9, 10, 11]);
§ 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_ref_from_bytes_static_size(source: &[u8]) -> Option<&format::LocoPacket> {
   zerocopy::FromBytes::ref_from_bytes(source).ok()
}
Assembly
bench_ref_from_bytes_static_size:
   mov ecx, edi
   and ecx, 1
   xor rsi, 6
   xor eax, eax
   or rsi, rcx
   cmove rax, rdi
   ret
Machine Code Analysis
Iterations:        100
Instructions:      700
Total Cycles:      240
Total uOps:        800

Dispatch Width:    4
uOps Per Cycle:    3.33
IPC:               2.92
Block RThroughput: 2.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	ecx, edi
1      1     0.33                        and	ecx, 1
1      1     0.33                        xor	rsi, 6
1      0     0.25                        xor	eax, eax
1      1     0.33                        or	rsi, rcx
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]  
-      -     2.33   2.33    -     2.34    -      -     

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.01   0.98    -     0.01    -      -     mov	ecx, edi
-      -     0.02   0.66    -     0.32    -      -     and	ecx, 1
-      -     0.33   0.66    -     0.01    -      -     xor	rsi, 6
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.98   0.02    -      -      -      -     or	rsi, rcx
-      -     0.99   0.01    -     1.00    -      -     cmove	rax, rdi
-      -      -      -      -     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_ref_from_bytes_dynamic_size(source: &[u8]) -> Option<&format::LocoPacket> {
   zerocopy::FromBytes::ref_from_bytes(source).ok()
}
Assembly
bench_ref_from_bytes_dynamic_size:
   mov rdx, rsi
   cmp rsi, 4
   setb al
   or al, dil
   test al, 1
   je .LBB5_2
   xor eax, eax
   ret
.LBB5_2:
   lea rcx, [rdx - 4]
   mov rsi, rcx
   and rsi, -2
   add rsi, 4
   shr rcx
   xor eax, eax
   cmp rdx, rsi
   cmove rdx, rcx
   cmove rax, rdi
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1800
Total Cycles:      704
Total uOps:        2000

Dispatch Width:    4
uOps Per Cycle:    2.84
IPC:               2.56
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	rdx, rsi
1      1     0.33                        cmp	rsi, 4
1      1     0.50                        setb	al
1      1     0.33                        or	al, dil
1      1     0.33                        test	al, 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, [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.50                        shr	rcx
1      0     0.25                        xor	eax, eax
1      1     0.33                        cmp	rdx, rsi
2      2     0.67                        cmove	rdx, rcx
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.97   5.98    -     6.05    -      -     

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.97   0.01    -     0.02    -      -     mov	rdx, rsi
-      -     0.01   0.02    -     0.97    -      -     cmp	rsi, 4
-      -     0.03    -      -     0.97    -      -     setb	al
-      -     0.01   0.02    -     0.97    -      -     or	al, dil
-      -      -     0.98    -     0.02    -      -     test	al, 1
-      -      -      -      -     1.00    -      -     je	.LBB5_2
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -      -      -     1.00    -      -     ret
-      -     0.98   0.02    -      -      -      -     lea	rcx, [rdx - 4]
-      -     0.01   0.99    -      -      -      -     mov	rsi, rcx
-      -      -     0.98    -     0.02    -      -     and	rsi, -2
-      -     0.98   0.01    -     0.01    -      -     add	rsi, 4
-      -     0.99    -      -     0.01    -      -     shr	rcx
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.02   0.97    -     0.01    -      -     cmp	rdx, rsi
-      -     0.99   0.99    -     0.02    -      -     cmove	rdx, rcx
-      -     0.98   0.99    -     0.03    -      -     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_ref_from_bytes_dynamic_padding(source: &[u8]) -> Option<&format::LocoPacket> {
   zerocopy::FromBytes::ref_from_bytes(source).ok()
}
Assembly
bench_ref_from_bytes_dynamic_padding:
   test dil, 3
   jne .LBB5_3
   movabs rax, 9223372036854775804
   and rax, rsi
   cmp rax, 9
   jb .LBB5_3
   add rax, -9
   movabs rcx, -6148914691236517205
   mul rcx
   shr rdx
   lea rax, [rdx + 2*rdx]
   or rax, 3
   add rax, 9
   cmp rsi, rax
   je .LBB5_4
.LBB5_3:
   xor edi, edi
   mov rdx, rsi
.LBB5_4:
   mov rax, rdi
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1900
Total Cycles:      645
Total uOps:        2000

Dispatch Width:    4
uOps Per Cycle:    3.10
IPC:               2.95
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                        test	dil, 3
1      1     1.00                        jne	.LBB5_3
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_3
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                        je	.LBB5_4
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.32   6.33    -     6.35    -      -     

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.64   0.35    -     0.01    -      -     test	dil, 3
-      -      -      -      -     1.00    -      -     jne	.LBB5_3
-      -     0.34   0.65    -     0.01    -      -     movabs	rax, 9223372036854775804
-      -     0.35   0.65    -      -      -      -     and	rax, rsi
-      -     0.33   0.34    -     0.33    -      -     cmp	rax, 9
-      -      -      -      -     1.00    -      -     jb	.LBB5_3
-      -     0.35    -      -     0.65    -      -     add	rax, -9
-      -     0.97   0.01    -     0.02    -      -     movabs	rcx, -6148914691236517205
-      -     1.00   1.00    -      -      -      -     mul	rcx
-      -     0.99    -      -     0.01    -      -     shr	rdx
-      -     0.33   0.67    -      -      -      -     lea	rax, [rdx + 2*rdx]
-      -     0.34   0.66    -      -      -      -     or	rax, 3
-      -     0.33   0.66    -     0.01    -      -     add	rax, 9
-      -     0.01   0.99    -      -      -      -     cmp	rsi, rax
-      -      -      -      -     1.00    -      -     je	.LBB5_4
-      -      -      -      -      -      -      -     xor	edi, edi
-      -     0.32   0.01    -     0.67    -      -     mov	rdx, rsi
-      -     0.02   0.34    -     0.64    -      -     mov	rax, rdi
-      -      -      -      -     1.00    -      -     ret
Source

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

Interprets the prefix of the given source as a &Self without copying.

This method computes the largest possible size of Self that can fit in the leading bytes of source, then attempts to return both a reference to those bytes interpreted as a Self, and a reference to the remaining bytes. If there are insufficient bytes, or if source is not appropriately aligned, 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. See ref_from_prefix_with_elems, which does support such types. Attempting to use this method on such types results in a compile-time assertion error; e.g.:

use zerocopy::*;

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

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

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct PacketHeader {
    src_port: [u8; 2],
    dst_port: [u8; 2],
    length: [u8; 2],
    checksum: [u8; 2],
}

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct Packet {
    header: PacketHeader,
    body: [[u8; 2]],
}

// These are more bytes than are needed to encode a `Packet`.
let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14][..];

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

assert_eq!(packet.header.src_port, [0, 1]);
assert_eq!(packet.header.dst_port, [2, 3]);
assert_eq!(packet.header.length, [4, 5]);
assert_eq!(packet.header.checksum, [6, 7]);
assert_eq!(packet.body, [[8, 9], [10, 11], [12, 13]]);
assert_eq!(suffix, &[14u8][..]);
§ 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_ref_from_prefix_static_size(source: &[u8]) -> Option<&format::LocoPacket> {
   match zerocopy::FromBytes::ref_from_prefix(source) {
       Ok((packet, _rest)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_ref_from_prefix_static_size:
   xor eax, eax
   cmp rsi, 6
   mov rcx, rdi
   cmovb rcx, rax
   test dil, 1
   cmove rax, rcx
   ret
Machine Code Analysis
Iterations:        100
Instructions:      700
Total Cycles:      274
Total uOps:        900

Dispatch Width:    4
uOps Per Cycle:    3.28
IPC:               2.55
Block RThroughput: 2.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	eax, eax
1      1     0.33                        cmp	rsi, 6
1      1     0.33                        mov	rcx, rdi
2      2     0.67                        cmovb	rcx, rax
1      1     0.33                        test	dil, 1
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]  
-      -     2.66   2.67    -     2.67    -      -     

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -     0.01    -     0.99    -      -     cmp	rsi, 6
-      -     0.01   0.67    -     0.32    -      -     mov	rcx, rdi
-      -     1.00   0.99    -     0.01    -      -     cmovb	rcx, rax
-      -     0.66   0.01    -     0.33    -      -     test	dil, 1
-      -     0.99   0.99    -     0.02    -      -     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_ref_from_prefix_dynamic_size(source: &[u8]) -> Option<&format::LocoPacket> {
   match zerocopy::FromBytes::ref_from_prefix(source) {
       Ok((packet, _rest)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_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
   mov rdx, rsi
   mov rax, rdi
.LBB5_4:
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1400
Total Cycles:      405
Total uOps:        1400

Dispatch Width:    4
uOps Per Cycle:    3.46
IPC:               3.46
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      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      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]  
-      -     3.99   3.99    -     4.02    -      -     

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -      -      -      -      -      -      -     xor	edx, edx
-      -     0.01   0.98    -     0.01    -      -     mov	eax, 0
-      -     0.98   0.02    -      -      -      -     test	dil, 1
-      -      -      -      -     1.00    -      -     jne	.LBB5_4
-      -     0.02   0.98    -      -      -      -     cmp	rsi, 4
-      -      -      -      -     1.00    -      -     jae	.LBB5_3
-      -     0.98   0.01    -     0.01    -      -     mov	edx, 1
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -      -      -     1.00    -      -     ret
-      -     0.01   0.99    -      -      -      -     add	rsi, -4
-      -     1.00    -      -      -      -      -     shr	rsi
-      -      -     1.00    -      -      -      -     mov	rdx, rsi
-      -     0.99   0.01    -      -      -      -     mov	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_ref_from_prefix_dynamic_padding(source: &[u8]) -> Option<&format::LocoPacket> {
   match zerocopy::FromBytes::ref_from_prefix(source) {
       Ok((packet, _rest)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_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
   shr rdx
   mov rax, rdi
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1900
Total Cycles:      608
Total uOps:        2000

Dispatch Width:    4
uOps Per Cycle:    3.29
IPC:               3.13
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      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.50                        shr	rdx
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.00   6.00    -     6.00    -      -     

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -      -      -      -      -      -      -     xor	edx, edx
-      -     0.01   0.98    -     0.01    -      -     mov	eax, 0
-      -     0.98   0.01    -     0.01    -      -     test	dil, 3
-      -      -      -      -     1.00    -      -     je	.LBB5_1
-      -      -      -      -     1.00    -      -     ret
-      -     0.01   0.99    -      -      -      -     movabs	rax, 9223372036854775804
-      -      -     1.00    -      -      -      -     and	rsi, rax
-      -      -     1.00    -      -      -      -     cmp	rsi, 9
-      -      -      -      -     1.00    -      -     jae	.LBB5_3
-      -     1.00    -      -      -      -      -     mov	edx, 1
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -      -      -     1.00    -      -     ret
-      -     0.02   0.02    -     0.96    -      -     add	rsi, -9
-      -     0.99   0.01    -      -      -      -     movabs	rcx, -6148914691236517205
-      -     0.01   0.99    -      -      -      -     mov	rax, rsi
-      -     1.00   1.00    -      -      -      -     mul	rcx
-      -     1.00    -      -      -      -      -     shr	rdx
-      -     0.98    -      -     0.02    -      -     mov	rax, rdi
-      -      -      -      -     1.00    -      -     ret
Source

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

Interprets the suffix of the given bytes as a &Self.

This method computes the largest possible size of Self that can fit in the trailing bytes of source, then attempts to return both a reference to those bytes interpreted as a Self, and a reference to the preceding bytes. If there are insufficient bytes, or if that suffix of source is not appropriately aligned, this returns Err. If 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. See ref_from_suffix_with_elems, which does support such types. Attempting to use this method on such types results in a compile-time assertion error; e.g.:

use zerocopy::*;

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

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

#[derive(FromBytes, Immutable, KnownLayout)]
#[repr(C)]
struct PacketTrailer {
    frame_check_sequence: [u8; 4],
}

// These are more bytes than are needed to encode a `PacketTrailer`.
let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];

let (prefix, trailer) = PacketTrailer::ref_from_suffix(bytes).unwrap();

assert_eq!(prefix, &[0, 1, 2, 3, 4, 5][..]);
assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);
§ 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_ref_from_suffix_static_size(source: &[u8]) -> Option<&format::LocoPacket> {
   match zerocopy::FromBytes::ref_from_suffix(source) {
       Ok((_rest, packet)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_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 rax, [rdi + rsi]
   add rax, -6
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1100
Total Cycles:      338
Total uOps:        1100

Dispatch Width:    4
uOps Per Cycle:    3.25
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.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	rax, [rdi + rsi]
1      1     0.33                        add	rax, -6
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.32   3.33    -     3.35    -      -     

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.97   0.03    -      -      -      -     lea	eax, [rsi + rdi]
-      -     0.33   0.32    -     0.35    -      -     cmp	rsi, 6
-      -     1.00    -      -      -      -      -     setb	cl
-      -      -     1.00    -      -      -      -     or	cl, al
-      -      -     1.00    -      -      -      -     test	cl, 1
-      -      -      -      -     1.00    -      -     je	.LBB5_2
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -      -      -     1.00    -      -     ret
-      -     0.34   0.66    -      -      -      -     lea	rax, [rdi + rsi]
-      -     0.68   0.32    -      -      -      -     add	rax, -6
-      -      -      -      -     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_ref_from_suffix_dynamic_size(source: &[u8]) -> Option<&format::LocoPacket> {
   match zerocopy::FromBytes::ref_from_suffix(source) {
       Ok((_rest, packet)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_ref_from_suffix_dynamic_size:
   mov rdx, rsi
   lea ecx, [rsi + rdi]
   mov eax, edx
   and eax, 1
   add rax, rdi
   xor esi, esi
   sub rdx, 4
   cmovb rax, rsi
   shr rdx
   test cl, 1
   cmovne rax, rsi
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1200
Total Cycles:      439
Total uOps:        1400

Dispatch Width:    4
uOps Per Cycle:    3.19
IPC:               2.73
Block RThroughput: 3.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	rdx, rsi
1      1     0.50                        lea	ecx, [rsi + rdi]
1      1     0.33                        mov	eax, edx
1      1     0.33                        and	eax, 1
1      1     0.33                        add	rax, rdi
1      0     0.25                        xor	esi, esi
1      1     0.33                        sub	rdx, 4
2      2     0.67                        cmovb	rax, rsi
1      1     0.50                        shr	rdx
1      1     0.33                        test	cl, 1
2      2     0.67                        cmovne	rax, 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.33   4.33    -     4.34    -      -     

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.02   0.32    -     0.66    -      -     mov	rdx, rsi
-      -     0.32   0.68    -      -      -      -     lea	ecx, [rsi + rdi]
-      -     0.66    -      -     0.34    -      -     mov	eax, edx
-      -     0.02   0.33    -     0.65    -      -     and	eax, 1
-      -      -     0.99    -     0.01    -      -     add	rax, rdi
-      -      -      -      -      -      -      -     xor	esi, esi
-      -     0.65    -      -     0.35    -      -     sub	rdx, 4
-      -     1.00   1.00    -      -      -      -     cmovb	rax, rsi
-      -     0.66    -      -     0.34    -      -     shr	rdx
-      -      -     0.01    -     0.99    -      -     test	cl, 1
-      -     1.00   1.00    -      -      -      -     cmovne	rax, 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_ref_from_suffix_dynamic_padding(source: &[u8]) -> Option<&format::LocoPacket> {
   match zerocopy::FromBytes::ref_from_suffix(source) {
       Ok((_rest, packet)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_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 rax, [rdx + 2*rdx]
   sub rsi, rax
   or rax, -4
   add rsi, rdi
   add rax, rsi
   add rax, -8
   ret
Machine Code Analysis
Iterations:        100
Instructions:      2000
Total Cycles:      682
Total uOps:        2100

Dispatch Width:    4
uOps Per Cycle:    3.08
IPC:               2.93
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.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	rax, [rdx + 2*rdx]
1      1     0.33                        sub	rsi, rax
1      1     0.33                        or	rax, -4
1      1     0.33                        add	rsi, rdi
1      1     0.33                        add	rax, rsi
1      1     0.33                        add	rax, -8
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.67    -     6.68    -      -     

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.90   0.10    -      -      -      -     lea	eax, [rsi + rdi]
-      -     0.93    -      -     0.07    -      -     test	al, 3
-      -      -      -      -     1.00    -      -     jne	.LBB5_1
-      -     0.51   0.47    -     0.02    -      -     movabs	rax, 9223372036854775804
-      -      -      -      -     1.00    -      -     and	rax, rsi
-      -      -     0.09    -     0.91    -      -     cmp	rax, 9
-      -      -      -      -     1.00    -      -     jae	.LBB5_3
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -      -      -     1.00    -      -     ret
-      -     0.43   0.47    -     0.10    -      -     add	rax, -9
-      -     0.42   0.39    -     0.19    -      -     movabs	rcx, -6148914691236517205
-      -     1.00   1.00    -      -      -      -     mul	rcx
-      -     0.69    -      -     0.31    -      -     shr	rdx
-      -     0.54   0.46    -      -      -      -     lea	rax, [rdx + 2*rdx]
-      -     0.07   0.91    -     0.02    -      -     sub	rsi, rax
-      -     0.91   0.05    -     0.04    -      -     or	rax, -4
-      -     0.08   0.90    -     0.02    -      -     add	rsi, rdi
-      -     0.09   0.91    -      -      -      -     add	rax, rsi
-      -     0.08   0.92    -      -      -      -     add	rax, -8
-      -      -      -      -     1.00    -      -     ret
Source

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

Interprets the given source as a &mut Self.

This method attempts to return a reference to source interpreted as a Self. If the length of source is not a valid size of Self, or if source is not appropriately aligned, 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. See mut_from_prefix_with_elems, which does support such types. Attempting to use this method on such types results in a compile-time assertion error; e.g.:

use zerocopy::*;

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

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

#[derive(FromBytes, IntoBytes, KnownLayout, Immutable)]
#[repr(C)]
struct PacketHeader {
    src_port: [u8; 2],
    dst_port: [u8; 2],
    length: [u8; 2],
    checksum: [u8; 2],
}

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

let header = PacketHeader::mut_from_bytes(bytes).unwrap();

assert_eq!(header.src_port, [0, 1]);
assert_eq!(header.dst_port, [2, 3]);
assert_eq!(header.length, [4, 5]);
assert_eq!(header.checksum, [6, 7]);

header.checksum = [0, 0];

assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0]);
§ Code Generation

See FromBytes::ref_from_bytes.

Source

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

Interprets the prefix of the given source as a &mut Self without copying.

This method computes the largest possible size of Self that can fit in the leading bytes of source, then attempts to return both a reference to those bytes interpreted as a Self, and a reference to the remaining bytes. If there are insufficient bytes, or if source is not appropriately aligned, 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. See mut_from_suffix_with_elems, which does support such types. Attempting to use this method on such types results in a compile-time assertion error; e.g.:

use zerocopy::*;

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

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

#[derive(FromBytes, IntoBytes, KnownLayout, Immutable)]
#[repr(C)]
struct PacketHeader {
    src_port: [u8; 2],
    dst_port: [u8; 2],
    length: [u8; 2],
    checksum: [u8; 2],
}

// These are more bytes than are needed to encode a `PacketHeader`.
let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];

let (header, body) = PacketHeader::mut_from_prefix(bytes).unwrap();

assert_eq!(header.src_port, [0, 1]);
assert_eq!(header.dst_port, [2, 3]);
assert_eq!(header.length, [4, 5]);
assert_eq!(header.checksum, [6, 7]);
assert_eq!(body, &[8, 9][..]);

header.checksum = [0, 0];
body.fill(1);

assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0, 1, 1]);
§ Code Generation

See FromBytes::ref_from_prefix.

Source

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

Interprets the suffix of the given source as a &mut Self without copying.

This method computes the largest possible size of Self that can fit in the trailing bytes of source, then attempts to return both a reference to those bytes interpreted as a Self, and a reference to the preceding bytes. If there are insufficient bytes, or if that suffix of source is not appropriately aligned, this returns Err. If 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(FromBytes, Immutable, IntoBytes, KnownLayout)]
#[repr(C, packed)]
struct ZSTy {
    leading_sized: [u8; 2],
    trailing_dst: [()],
}

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

#[derive(FromBytes, IntoBytes, KnownLayout, Immutable)]
#[repr(C)]
struct PacketTrailer {
    frame_check_sequence: [u8; 4],
}

// These are more bytes than are needed to encode a `PacketTrailer`.
let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];

let (prefix, trailer) = PacketTrailer::mut_from_suffix(bytes).unwrap();

assert_eq!(prefix, &[0u8, 1, 2, 3, 4, 5][..]);
assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);

prefix.fill(0);
trailer.frame_check_sequence.fill(1);

assert_eq!(bytes, [0, 0, 0, 0, 0, 0, 1, 1, 1, 1]);
§ Code Generation

See FromBytes::ref_from_suffix.

Source

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

Interprets 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, or if source is not appropriately aligned, this returns Err. If Self: Unaligned, you can infallibly discard the alignment error.

§Examples
use zerocopy::FromBytes;

#[derive(FromBytes, Immutable)]
#[repr(C)]
struct Pixel {
    r: u8,
    g: u8,
    b: u8,
    a: u8,
}

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

let pixels = <[Pixel]>::ref_from_bytes_with_elems(bytes, 2).unwrap();

assert_eq!(pixels, &[
    Pixel { r: 0, g: 1, b: 2, a: 3 },
    Pixel { r: 4, g: 5, b: 6, a: 7 },
]);

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

use zerocopy::*;

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

let src = &[85, 85][..];
let zsty = ZSTy::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_ref_from_bytes_with_elems_dynamic_size(
   source: &[u8],
   count: usize,
) -> Option<&format::LocoPacket> {
   zerocopy::FromBytes::ref_from_bytes_with_elems(source, count).ok()
}
Assembly
bench_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_2
   lea rcx, [2*rdx + 4]
   cmp rsi, rcx
   je .LBB5_3
.LBB5_2:
   xor eax, eax
   mov rdx, rsi
.LBB5_3:
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1300
Total Cycles:      439
Total uOps:        1400

Dispatch Width:    4
uOps Per Cycle:    3.19
IPC:               2.96
Block RThroughput: 3.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
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_2
1      1     0.50                        lea	rcx, [2*rdx + 4]
1      1     0.33                        cmp	rsi, rcx
1      1     1.00                        je	.LBB5_3
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.32   4.33    -     4.35    -      -     

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -      -     0.99    -     0.01    -      -     movabs	rax, 9223372036854775805
-      -     0.33   0.67    -      -      -      -     cmp	rdx, rax
-      -     1.98    -      -     0.02    -      -     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_2
-      -      -     1.00    -      -      -      -     lea	rcx, [2*rdx + 4]
-      -     0.01    -      -     0.99    -      -     cmp	rsi, rcx
-      -      -      -      -     1.00    -      -     je	.LBB5_3
-      -      -      -      -      -      -      -     xor	eax, eax
-      -      -     0.67    -     0.33    -      -     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_ref_from_bytes_with_elems_dynamic_padding(
   source: &[u8],
   count: usize,
) -> Option<&format::LocoPacket> {
   zerocopy::FromBytes::ref_from_bytes_with_elems(source, count).ok()
}
Assembly
bench_ref_from_bytes_with_elems_dynamic_padding:
   mov rcx, rdx
   mov edx, 3
   mov rax, rcx
   mul rdx
   jo .LBB5_5
   cmp rax, -10
   ja .LBB5_5
   mov edx, eax
   not edx
   and edx, 3
   add rdx, rax
   add rdx, 9
   cmp rsi, rdx
   jne .LBB5_5
   mov r8d, edi
   and r8d, 3
   jne .LBB5_5
   add rax, 9
   cmp rdx, rax
   jb .LBB5_5
   mov rax, rdi
   mov rdx, rcx
   ret
.LBB5_5:
   xor edi, edi
   mov rcx, rsi
   mov rax, rdi
   mov rdx, rcx
   ret
Machine Code Analysis
Iterations:        100
Instructions:      2800
Total Cycles:      944
Total uOps:        2900

Dispatch Width:    4
uOps Per Cycle:    3.07
IPC:               2.97
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      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_5
1      1     0.33                        cmp	rax, -10
1      1     1.00                        ja	.LBB5_5
1      1     0.33                        mov	edx, eax
1      1     0.33                        not	edx
1      1     0.33                        and	edx, 3
1      1     0.33                        add	rdx, rax
1      1     0.33                        add	rdx, 9
1      1     0.33                        cmp	rsi, rdx
1      1     1.00                        jne	.LBB5_5
1      1     0.33                        mov	r8d, edi
1      1     0.33                        and	r8d, 3
1      1     1.00                        jne	.LBB5_5
1      1     0.33                        add	rax, 9
1      1     0.33                        cmp	rdx, rax
1      1     1.00                        jb	.LBB5_5
1      1     0.33                        mov	rax, rdi
1      1     0.33                        mov	rdx, rcx
1      1     1.00                  U     ret
1      0     0.25                        xor	edi, edi
1      1     0.33                        mov	rcx, rsi
1      1     0.33                        mov	rax, rdi
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]  
-      -     9.32   9.32    -     9.36    -      -     

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.64   0.18    -     0.18    -      -     mov	rcx, rdx
-      -     0.17   0.83    -      -      -      -     mov	edx, 3
-      -     0.50   0.49    -     0.01    -      -     mov	rax, rcx
-      -     1.00   1.00    -      -      -      -     mul	rdx
-      -      -      -      -     1.00    -      -     jo	.LBB5_5
-      -     0.82   0.18    -      -      -      -     cmp	rax, -10
-      -      -      -      -     1.00    -      -     ja	.LBB5_5
-      -     0.02   0.98    -      -      -      -     mov	edx, eax
-      -     0.82   0.02    -     0.16    -      -     not	edx
-      -     0.82   0.17    -     0.01    -      -     and	edx, 3
-      -     0.99    -      -     0.01    -      -     add	rdx, rax
-      -     0.98   0.01    -     0.01    -      -     add	rdx, 9
-      -     1.00    -      -      -      -      -     cmp	rsi, rdx
-      -      -      -      -     1.00    -      -     jne	.LBB5_5
-      -     0.16   0.83    -     0.01    -      -     mov	r8d, edi
-      -     0.17   0.17    -     0.66    -      -     and	r8d, 3
-      -      -      -      -     1.00    -      -     jne	.LBB5_5
-      -     0.02   0.98    -      -      -      -     add	rax, 9
-      -      -     0.17    -     0.83    -      -     cmp	rdx, rax
-      -      -      -      -     1.00    -      -     jb	.LBB5_5
-      -     0.01   0.67    -     0.32    -      -     mov	rax, rdi
-      -     0.02   0.98    -      -      -      -     mov	rdx, rcx
-      -      -      -      -     1.00    -      -     ret
-      -      -      -      -      -      -      -     xor	edi, edi
-      -     0.34   0.66    -      -      -      -     mov	rcx, rsi
-      -     0.34   0.50    -     0.16    -      -     mov	rax, rdi
-      -     0.50   0.50    -      -      -      -     mov	rdx, rcx
-      -      -      -      -     1.00    -      -     ret
Source

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

Interprets the prefix of the given source as a DST &Self with 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 there are insufficient bytes, or if source is not appropriately aligned, this returns Err. If Self: Unaligned, you can infallibly discard the alignment error.

§Examples
use zerocopy::FromBytes;

#[derive(FromBytes, Immutable)]
#[repr(C)]
struct Pixel {
    r: u8,
    g: u8,
    b: u8,
    a: u8,
}

// These are more bytes than are needed to encode two `Pixel`s.
let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];

let (pixels, suffix) = <[Pixel]>::ref_from_prefix_with_elems(bytes, 2).unwrap();

assert_eq!(pixels, &[
    Pixel { r: 0, g: 1, b: 2, a: 3 },
    Pixel { r: 4, g: 5, b: 6, a: 7 },
]);

assert_eq!(suffix, &[8, 9]);

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

use zerocopy::*;

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

let src = &[85, 85][..];
let (zsty, _) = ZSTy::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_ref_from_prefix_with_elems_dynamic_size(
   source: &[u8],
   count: usize,
) -> Option<&format::LocoPacket> {
   match zerocopy::FromBytes::ref_from_prefix_with_elems(source, count) {
       Ok((packet, _rest)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_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_4
   lea rax, [2*rcx + 4]
   xor r8d, r8d
   cmp rax, rsi
   mov edx, 1
   cmovbe rdx, rcx
   cmova rdi, r8
   mov rax, rdi
.LBB5_4:
   ret
.LBB5_1:
   mov edx, 1
   xor eax, eax
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1900
Total Cycles:      672
Total uOps:        2300

Dispatch Width:    4
uOps Per Cycle:    3.42
IPC:               2.83
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                        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_4
1      1     0.50                        lea	rax, [2*rcx + 4]
1      0     0.25                        xor	r8d, r8d
1      1     0.33                        cmp	rax, rsi
1      1     0.33                        mov	edx, 1
3      3     1.00                        cmovbe	rdx, rcx
3      3     1.00                        cmova	rdi, r8
1      1     0.33                        mov	rax, rdi
1      1     1.00                  U     ret
1      1     0.33                        mov	edx, 1
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.66   6.66    -     6.68    -      -     

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -      -     0.99    -     0.01    -      -     movabs	rax, 9223372036854775805
-      -     0.37   0.63    -      -      -      -     cmp	rdx, rax
-      -      -      -      -     1.00    -      -     ja	.LBB5_1
-      -     0.63   0.37    -      -      -      -     mov	rcx, rdx
-      -      -      -      -      -      -      -     xor	edx, edx
-      -     0.01   0.98    -     0.01    -      -     mov	eax, 0
-      -     0.98   0.02    -      -      -      -     test	dil, 1
-      -      -      -      -     1.00    -      -     jne	.LBB5_4
-      -     0.01   0.99    -      -      -      -     lea	rax, [2*rcx + 4]
-      -      -      -      -      -      -      -     xor	r8d, r8d
-      -     1.00    -      -      -      -      -     cmp	rax, rsi
-      -      -     0.67    -     0.33    -      -     mov	edx, 1
-      -     0.73   0.98    -     1.29    -      -     cmovbe	rdx, rcx
-      -     1.60   0.36    -     1.04    -      -     cmova	rdi, r8
-      -     0.99   0.01    -      -      -      -     mov	rax, rdi
-      -      -      -      -     1.00    -      -     ret
-      -     0.34   0.66    -      -      -      -     mov	edx, 1
-      -      -      -      -      -      -      -     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_ref_from_prefix_with_elems_dynamic_padding(
   source: &[u8],
   count: usize,
) -> Option<&format::LocoPacket> {
   match zerocopy::FromBytes::ref_from_prefix_with_elems(source, count) {
       Ok((packet, _rest)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_ref_from_prefix_with_elems_dynamic_padding:
   mov rcx, rdx
   mov edx, 3
   mov rax, rcx
   mul rdx
   mov edx, 1
   jo .LBB5_5
   cmp rax, -10
   ja .LBB5_5
   lea r8, [rax + 9]
   not eax
   and eax, 3
   add rax, r8
   jae .LBB5_3
.LBB5_5:
   xor r8d, r8d
   mov rax, r8
   ret
.LBB5_3:
   xor edx, edx
   mov r8d, 0
   test dil, 3
   je .LBB5_4
   mov rax, r8
   ret
.LBB5_4:
   xor edx, edx
   cmp rax, rsi
   mov eax, 1
   cmova rcx, rax
   cmova rdi, rdx
   mov rdx, rcx
   mov r8, rdi
   mov rax, r8
   ret
Machine Code Analysis
Iterations:        100
Instructions:      3100
Total Cycles:      1110
Total uOps:        3600

Dispatch Width:    4
uOps Per Cycle:    3.24
IPC:               2.79
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     0.33                        mov	edx, 1
1      1     1.00                        jo	.LBB5_5
1      1     0.33                        cmp	rax, -10
1      1     1.00                        ja	.LBB5_5
1      1     0.50                        lea	r8, [rax + 9]
1      1     0.33                        not	eax
1      1     0.33                        and	eax, 3
1      1     0.33                        add	rax, r8
1      1     1.00                        jae	.LBB5_3
1      0     0.25                        xor	r8d, r8d
1      1     0.33                        mov	rax, r8
1      1     1.00                  U     ret
1      0     0.25                        xor	edx, edx
1      1     0.33                        mov	r8d, 0
1      1     0.33                        test	dil, 3
1      1     1.00                        je	.LBB5_4
1      1     0.33                        mov	rax, r8
1      1     1.00                  U     ret
1      0     0.25                        xor	edx, edx
1      1     0.33                        cmp	rax, rsi
1      1     0.33                        mov	eax, 1
3      3     1.00                        cmova	rcx, rax
3      3     1.00                        cmova	rdi, rdx
1      1     0.33                        mov	rdx, rcx
1      1     0.33                        mov	r8, rdi
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.01  10.98   -     11.01   -      -     

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.48   0.50    -     0.02    -      -     mov	rcx, rdx
-      -     0.02   0.98    -      -      -      -     mov	edx, 3
-      -     0.51   0.48    -     0.01    -      -     mov	rax, rcx
-      -     1.00   1.00    -      -      -      -     mul	rdx
-      -     0.49   0.50    -     0.01    -      -     mov	edx, 1
-      -      -      -      -     1.00    -      -     jo	.LBB5_5
-      -     0.98   0.02    -      -      -      -     cmp	rax, -10
-      -      -      -      -     1.00    -      -     ja	.LBB5_5
-      -     0.02   0.98    -      -      -      -     lea	r8, [rax + 9]
-      -     0.98   0.02    -      -      -      -     not	eax
-      -     0.99   0.01    -      -      -      -     and	eax, 3
-      -     0.98   0.01    -     0.01    -      -     add	rax, r8
-      -      -      -      -     1.00    -      -     jae	.LBB5_3
-      -      -      -      -      -      -      -     xor	r8d, r8d
-      -     0.01   0.98    -     0.01    -      -     mov	rax, r8
-      -      -      -      -     1.00    -      -     ret
-      -      -      -      -      -      -      -     xor	edx, edx
-      -     0.48   0.52    -      -      -      -     mov	r8d, 0
-      -     0.02   0.97    -     0.01    -      -     test	dil, 3
-      -      -      -      -     1.00    -      -     je	.LBB5_4
-      -     0.49   0.50    -     0.01    -      -     mov	rax, r8
-      -      -      -      -     1.00    -      -     ret
-      -      -      -      -      -      -      -     xor	edx, edx
-      -     0.51   0.49    -      -      -      -     cmp	rax, rsi
-      -      -     1.00    -      -      -      -     mov	eax, 1
-      -     1.04   0.97    -     0.99    -      -     cmova	rcx, rax
-      -     0.98   0.53    -     1.49    -      -     cmova	rdi, rdx
-      -     0.50   0.50    -      -      -      -     mov	rdx, rcx
-      -     0.51   0.01    -     0.48    -      -     mov	r8, rdi
-      -     0.02   0.01    -     0.97    -      -     mov	rax, r8
-      -      -      -      -     1.00    -      -     ret
Source

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

Interprets the suffix of the given source as a DST &Self with 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 there are insufficient bytes, or if that suffix of source is not appropriately aligned, this returns Err. If Self: Unaligned, you can infallibly discard the alignment error.

§Examples
use zerocopy::FromBytes;

#[derive(FromBytes, Immutable)]
#[repr(C)]
struct Pixel {
    r: u8,
    g: u8,
    b: u8,
    a: u8,
}

// These are more bytes than are needed to encode two `Pixel`s.
let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];

let (prefix, pixels) = <[Pixel]>::ref_from_suffix_with_elems(bytes, 2).unwrap();

assert_eq!(prefix, &[0, 1]);

assert_eq!(pixels, &[
    Pixel { r: 2, g: 3, b: 4, a: 5 },
    Pixel { r: 6, g: 7, b: 8, a: 9 },
]);

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

use zerocopy::*;

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

let src = &[85, 85][..];
let (_, zsty) = ZSTy::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_ref_from_suffix_with_elems_dynamic_size(
   source: &[u8],
   count: usize,
) -> Option<&format::LocoPacket> {
   match zerocopy::FromBytes::ref_from_suffix_with_elems(source, count) {
       Ok((_rest, packet)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_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:
   add rdi, rsi
   mov rcx, rdx
   mov rax, rdi
.LBB5_5:
   mov rdx, rcx
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1900
Total Cycles:      571
Total uOps:        1900

Dispatch Width:    4
uOps Per Cycle:    3.33
IPC:               3.33
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                        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.33                        add	rdi, rsi
1      1     0.33                        mov	rcx, rdx
1      1     0.33                        mov	rax, rdi
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]  
-      -     5.66   5.66    -     5.68    -      -     

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.01   0.99    -      -      -      -     cmp	rdx, rax
-      -      -      -      -     1.00    -      -     ja	.LBB5_1
-      -     0.99   0.01    -      -      -      -     lea	r8d, [rsi + rdi]
-      -      -      -      -      -      -      -     xor	ecx, ecx
-      -     0.33   0.33    -     0.34    -      -     mov	eax, 0
-      -     0.33   0.34    -     0.33    -      -     test	r8b, 1
-      -      -      -      -     1.00    -      -     jne	.LBB5_5
-      -     0.34   0.66    -      -      -      -     lea	rax, [2*rdx + 4]
-      -      -     1.00    -      -      -      -     sub	rsi, rax
-      -      -      -      -     1.00    -      -     jae	.LBB5_4
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     1.00    -      -      -      -      -     mov	edx, 1
-      -      -      -      -     1.00    -      -     ret
-      -      -     1.00    -      -      -      -     add	rdi, rsi
-      -     1.00    -      -      -      -      -     mov	rcx, rdx
-      -     0.32   0.68    -      -      -      -     mov	rax, rdi
-      -     0.68   0.32    -      -      -      -     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_ref_from_suffix_with_elems_dynamic_padding(
   source: &[u8],
   count: usize,
) -> Option<&format::LocoPacket> {
   match zerocopy::FromBytes::ref_from_suffix_with_elems(source, count) {
       Ok((_rest, packet)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_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
   add rdi, rsi
   mov rdx, rcx
   mov r8, rdi
   mov rax, r8
   ret
Machine Code Analysis
Iterations:        100
Instructions:      3000
Total Cycles:      973
Total uOps:        3100

Dispatch Width:    4
uOps Per Cycle:    3.19
IPC:               3.08
Block RThroughput: 8.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_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.33                        add	rdi, rsi
1      1     0.33                        mov	rdx, rcx
1      1     0.33                        mov	r8, rdi
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]  
-      -     9.66   9.66    -     9.68    -      -     

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -      -     0.99    -     0.01    -      -     mov	rcx, rdx
-      -     0.66   0.34    -      -      -      -     mov	edx, 3
-      -     0.34   0.66    -      -      -      -     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
-      -     1.00    -      -      -      -      -     and	eax, 3
-      -     1.00    -      -      -      -      -     add	rax, rdx
-      -      -      -      -     1.00    -      -     jae	.LBB5_4
-      -      -      -      -      -      -      -     xor	r8d, r8d
-      -     0.33   0.33    -     0.34    -      -     mov	edx, 1
-      -     0.33    -      -     0.67    -      -     mov	rax, r8
-      -      -      -      -     1.00    -      -     ret
-      -     0.33   0.67    -      -      -      -     lea	r9d, [rsi + rdi]
-      -      -      -      -      -      -      -     xor	edx, edx
-      -     0.67   0.33    -      -      -      -     mov	r8d, 0
-      -     0.33   0.34    -     0.33    -      -     test	r9b, 3
-      -      -      -      -     1.00    -      -     je	.LBB5_5
-      -     0.66   0.01    -     0.33    -      -     mov	rax, r8
-      -      -      -      -     1.00    -      -     ret
-      -     0.33   0.67    -      -      -      -     sub	rsi, rax
-      -      -      -      -     1.00    -      -     jb	.LBB5_1
-      -      -     1.00    -      -      -      -     add	rdi, rsi
-      -     0.01   0.99    -      -      -      -     mov	rdx, rcx
-      -      -     1.00    -      -      -      -     mov	r8, rdi
-      -     0.67   0.33    -      -      -      -     mov	rax, r8
-      -      -      -      -     1.00    -      -     ret
Source

fn mut_from_bytes_with_elems( source: &mut [u8], count: usize, ) -> Result<&mut Self, CastError<&mut [u8], Self>>
where Self: IntoBytes + KnownLayout<PointerMetadata = usize> + Immutable,

Interprets 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, or if source is not appropriately aligned, this returns Err. If Self: Unaligned, you can infallibly discard the alignment error.

§Examples
use zerocopy::FromBytes;

#[derive(KnownLayout, FromBytes, IntoBytes, Immutable)]
#[repr(C)]
struct Pixel {
    r: u8,
    g: u8,
    b: u8,
    a: u8,
}

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

let pixels = <[Pixel]>::mut_from_bytes_with_elems(bytes, 2).unwrap();

assert_eq!(pixels, &[
    Pixel { r: 0, g: 1, b: 2, a: 3 },
    Pixel { r: 4, g: 5, b: 6, a: 7 },
]);

pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };

assert_eq!(bytes, [0, 1, 2, 3, 0, 0, 0, 0]);

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

use zerocopy::*;

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

let src = &mut [85, 85][..];
let zsty = ZSTy::mut_from_bytes_with_elems(src, 42).unwrap();
assert_eq!(zsty.trailing_dst.len(), 42);
§ Code Generation

See TryFromBytes::ref_from_bytes_with_elems.

Source

fn mut_from_prefix_with_elems( source: &mut [u8], count: usize, ) -> Result<(&mut Self, &mut [u8]), CastError<&mut [u8], Self>>
where Self: IntoBytes + KnownLayout<PointerMetadata = usize>,

Interprets the prefix of the given source as a &mut Self with 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 preceding bytes. If there are insufficient bytes, or if source is not appropriately aligned, this returns Err. If Self: Unaligned, you can infallibly discard the alignment error.

§Examples
use zerocopy::FromBytes;

#[derive(KnownLayout, FromBytes, IntoBytes, Immutable)]
#[repr(C)]
struct Pixel {
    r: u8,
    g: u8,
    b: u8,
    a: u8,
}

// These are more bytes than are needed to encode two `Pixel`s.
let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];

let (pixels, suffix) = <[Pixel]>::mut_from_prefix_with_elems(bytes, 2).unwrap();

assert_eq!(pixels, &[
    Pixel { r: 0, g: 1, b: 2, a: 3 },
    Pixel { r: 4, g: 5, b: 6, a: 7 },
]);

assert_eq!(suffix, &[8, 9]);

pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };
suffix.fill(1);

assert_eq!(bytes, [0, 1, 2, 3, 0, 0, 0, 0, 1, 1]);

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

use zerocopy::*;

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

let src = &mut [85, 85][..];
let (zsty, _) = ZSTy::mut_from_prefix_with_elems(src, 42).unwrap();
assert_eq!(zsty.trailing_dst.len(), 42);
§ Code Generation

See TryFromBytes::ref_from_prefix_with_elems.

Source

fn mut_from_suffix_with_elems( source: &mut [u8], count: usize, ) -> Result<(&mut [u8], &mut Self), CastError<&mut [u8], Self>>
where Self: IntoBytes + KnownLayout<PointerMetadata = usize>,

Interprets the suffix of the given source as a &mut Self with 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 remaining bytes. If there are insufficient bytes, or if that suffix of source is not appropriately aligned, this returns Err. If Self: Unaligned, you can infallibly discard the alignment error.

§Examples
use zerocopy::FromBytes;

#[derive(FromBytes, IntoBytes, Immutable)]
#[repr(C)]
struct Pixel {
    r: u8,
    g: u8,
    b: u8,
    a: u8,
}

// These are more bytes than are needed to encode two `Pixel`s.
let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];

let (prefix, pixels) = <[Pixel]>::mut_from_suffix_with_elems(bytes, 2).unwrap();

assert_eq!(prefix, &[0, 1]);

assert_eq!(pixels, &[
    Pixel { r: 2, g: 3, b: 4, a: 5 },
    Pixel { r: 6, g: 7, b: 8, a: 9 },
]);

prefix.fill(9);
pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };

assert_eq!(bytes, [9, 9, 2, 3, 4, 5, 0, 0, 0, 0]);

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

use zerocopy::*;

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

let src = &mut [85, 85][..];
let (_, zsty) = ZSTy::mut_from_suffix_with_elems(src, 42).unwrap();
assert_eq!(zsty.trailing_dst.len(), 42);
§ Code Generation

See TryFromBytes::ref_from_suffix_with_elems.

Source

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

Reads a copy of Self from the given source.

If source.len() != size_of::<Self>(), read_from_bytes returns Err.

§Examples
use zerocopy::FromBytes;

#[derive(FromBytes)]
#[repr(C)]
struct PacketHeader {
    src_port: [u8; 2],
    dst_port: [u8; 2],
    length: [u8; 2],
    checksum: [u8; 2],
}

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

let header = PacketHeader::read_from_bytes(bytes).unwrap();

assert_eq!(header.src_port, [0, 1]);
assert_eq!(header.dst_port, [2, 3]);
assert_eq!(header.length, [4, 5]);
assert_eq!(header.checksum, [6, 7]);
§ 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_read_from_bytes_static_size(source: &[u8]) -> Option<format::LocoPacket> {
   zerocopy::FromBytes::read_from_bytes(source).ok()
}
Assembly
bench_read_from_bytes_static_size:
   mov rcx, rsi
   cmp rsi, 6
   jne .LBB5_2
   mov eax, dword ptr [rdi]
   movzx ecx, word ptr [rdi + 4]
   shl rcx, 32
   or rcx, rax
.LBB5_2:
   shl rcx, 16
   inc rcx
   xor eax, eax
   cmp rsi, 6
   cmove rax, rcx
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1300
Total Cycles:      377
Total uOps:        1400

Dispatch Width:    4
uOps Per Cycle:    3.71
IPC:               3.45
Block RThroughput: 3.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, rsi
1      1     0.33                        cmp	rsi, 6
1      1     1.00                        jne	.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.50                        shl	rcx, 16
1      1     0.33                        inc	rcx
1      0     0.25                        xor	eax, eax
1      1     0.33                        cmp	rsi, 6
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]  
-      -     3.66   3.67    -     3.67   1.00   1.00   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.63   0.36    -     0.01    -      -     mov	rcx, rsi
-      -     0.05   0.05    -     0.90    -      -     cmp	rsi, 6
-      -      -      -      -     1.00    -      -     jne	.LBB5_2
-      -      -      -      -      -      -     1.00   mov	eax, dword ptr [rdi]
-      -      -      -      -      -     1.00    -     movzx	ecx, word ptr [rdi + 4]
-      -     0.97    -      -     0.03    -      -     shl	rcx, 32
-      -     0.02   0.35    -     0.63    -      -     or	rcx, rax
-      -     0.98    -      -     0.02    -      -     shl	rcx, 16
-      -      -     0.98    -     0.02    -      -     inc	rcx
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.03   0.93    -     0.04    -      -     cmp	rsi, 6
-      -     0.98   1.00    -     0.02    -      -     cmove	rax, rcx
-      -      -      -      -     1.00    -      -     ret
Source

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

Reads a copy of 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>(), it returns Err.

§Examples
use zerocopy::FromBytes;

#[derive(FromBytes)]
#[repr(C)]
struct PacketHeader {
    src_port: [u8; 2],
    dst_port: [u8; 2],
    length: [u8; 2],
    checksum: [u8; 2],
}

// These are more bytes than are needed to encode a `PacketHeader`.
let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];

let (header, body) = PacketHeader::read_from_prefix(bytes).unwrap();

assert_eq!(header.src_port, [0, 1]);
assert_eq!(header.dst_port, [2, 3]);
assert_eq!(header.length, [4, 5]);
assert_eq!(header.checksum, [6, 7]);
assert_eq!(body, [8, 9]);
§ 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_read_from_prefix_static_size(source: &[u8]) -> Option<format::LocoPacket> {
   match zerocopy::FromBytes::read_from_prefix(source) {
       Ok((packet, _rest)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_read_from_prefix_static_size:
   cmp rsi, 5
   jbe .LBB5_2
   mov eax, dword ptr [rdi]
   movzx edi, word ptr [rdi + 4]
   shl rdi, 32
   or rdi, rax
.LBB5_2:
   shl rdi, 16
   inc rdi
   xor eax, eax
   cmp rsi, 6
   cmovae rax, rdi
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1200
Total Cycles:      905
Total uOps:        1300

Dispatch Width:    4
uOps Per Cycle:    1.44
IPC:               1.33
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, 5
1      1     1.00                        jbe	.LBB5_2
1      5     0.50    *                   mov	eax, dword ptr [rdi]
1      5     0.50    *                   movzx	edi, word ptr [rdi + 4]
1      1     0.50                        shl	rdi, 32
1      1     0.33                        or	rdi, rax
1      1     0.50                        shl	rdi, 16
1      1     0.33                        inc	rdi
1      0     0.25                        xor	eax, eax
1      1     0.33                        cmp	rsi, 6
2      2     0.67                        cmovae	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]  
-      -     3.32   3.32    -     3.36   1.00   1.00   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.05   0.94    -     0.01    -      -     cmp	rsi, 5
-      -      -      -      -     1.00    -      -     jbe	.LBB5_2
-      -      -      -      -      -      -     1.00   mov	eax, dword ptr [rdi]
-      -      -      -      -      -     1.00    -     movzx	edi, word ptr [rdi + 4]
-      -     0.71    -      -     0.29    -      -     shl	rdi, 32
-      -      -     0.64    -     0.36    -      -     or	rdi, rax
-      -     1.00    -      -      -      -      -     shl	rdi, 16
-      -     0.31   0.40    -     0.29    -      -     inc	rdi
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.34   0.35    -     0.31    -      -     cmp	rsi, 6
-      -     0.91   0.99    -     0.10    -      -     cmovae	rax, rdi
-      -      -      -      -     1.00    -      -     ret
Source

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

Reads a copy of 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>(), it returns Err.

§Examples
use zerocopy::FromBytes;

#[derive(FromBytes)]
#[repr(C)]
struct PacketTrailer {
    frame_check_sequence: [u8; 4],
}

// These are more bytes than are needed to encode a `PacketTrailer`.
let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];

let (prefix, trailer) = PacketTrailer::read_from_suffix(bytes).unwrap();

assert_eq!(prefix, [0, 1, 2, 3, 4, 5]);
assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);
§ 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_read_from_suffix_static_size(source: &[u8]) -> Option<format::LocoPacket> {
   match zerocopy::FromBytes::read_from_suffix(source) {
       Ok((_rest, packet)) => Some(packet),
       _ => None,
   }
}
Assembly
bench_read_from_suffix_static_size:
   mov rcx, rsi
   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
.LBB5_2:
   shl rcx, 16
   inc rcx
   xor eax, eax
   cmp rsi, 6
   cmovae rax, rcx
   ret
Machine Code Analysis
Iterations:        100
Instructions:      1300
Total Cycles:      377
Total uOps:        1400

Dispatch Width:    4
uOps Per Cycle:    3.71
IPC:               3.45
Block RThroughput: 3.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, rsi
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.50                        shl	rcx, 16
1      1     0.33                        inc	rcx
1      0     0.25                        xor	eax, eax
1      1     0.33                        cmp	rsi, 6
2      2     0.67                        cmovae	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]  
-      -     3.66   3.67    -     3.67   1.00   1.00   

Resource pressure by instruction:
[0]    [1]    [2]    [3]    [4]    [5]    [6.0]  [6.1]  Instructions:
-      -     0.63   0.36    -     0.01    -      -     mov	rcx, rsi
-      -     0.05   0.05    -     0.90    -      -     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.97    -      -     0.03    -      -     shl	rcx, 32
-      -     0.02   0.35    -     0.63    -      -     or	rcx, rax
-      -     0.98    -      -     0.02    -      -     shl	rcx, 16
-      -      -     0.98    -     0.02    -      -     inc	rcx
-      -      -      -      -      -      -      -     xor	eax, eax
-      -     0.03   0.93    -     0.04    -      -     cmp	rsi, 6
-      -     0.98   1.00    -     0.02    -      -     cmovae	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 FromBytes for Option<NonZeroI8>

Source§

impl FromBytes for Option<NonZeroI16>

Source§

impl FromBytes for Option<NonZeroI32>

Source§

impl FromBytes for Option<NonZeroI64>

Source§

impl FromBytes for Option<NonZeroI128>

Source§

impl FromBytes for Option<NonZeroIsize>

Source§

impl FromBytes for Option<NonZeroU8>

Source§

impl FromBytes for Option<NonZeroU16>

Source§

impl FromBytes for Option<NonZeroU32>

Source§

impl FromBytes for Option<NonZeroU64>

Source§

impl FromBytes for Option<NonZeroU128>

Source§

impl FromBytes for Option<NonZeroUsize>

Source§

impl FromBytes for f32

Source§

impl FromBytes for f64

Source§

impl FromBytes for i8

Source§

impl FromBytes for i16

Source§

impl FromBytes for i32

Source§

impl FromBytes for i64

Source§

impl FromBytes for i128

Source§

impl FromBytes for isize

Source§

impl FromBytes for u8

Source§

impl FromBytes for u16

Source§

impl FromBytes for u32

Source§

impl FromBytes for u64

Source§

impl FromBytes for u128

Source§

impl FromBytes for ()

Source§

impl FromBytes for usize

Source§

impl FromBytes for __m128

Source§

impl FromBytes for __m128d

Source§

impl FromBytes for __m128i

Source§

impl FromBytes for __m256

Source§

impl FromBytes for __m256d

Source§

impl FromBytes for __m256i

Source§

impl FromBytes for __m512

Source§

impl FromBytes for __m512bh

Source§

impl FromBytes for __m512d

Source§

impl FromBytes for __m512i

Source§

impl FromBytes for AtomicI8

Source§

impl FromBytes for AtomicI16

Source§

impl FromBytes for AtomicI32

Source§

impl FromBytes for AtomicI64

Source§

impl FromBytes for AtomicIsize

Source§

impl FromBytes for AtomicU8

Source§

impl FromBytes for AtomicU16

Source§

impl FromBytes for AtomicU32

Source§

impl FromBytes for AtomicU64

Source§

impl FromBytes for AtomicUsize

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

impl<A: FromBytes, B: FromBytes, C: FromBytes, D: FromBytes, E: FromBytes, F: FromBytes, G: FromBytes, H: FromBytes, I: FromBytes, J: FromBytes, K: FromBytes, L: FromBytes, M: FromBytes, N: FromBytes, O: FromBytes, P: FromBytes, Q: FromBytes, R: FromBytes, S: FromBytes, T: FromBytes, U: FromBytes> FromBytes 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: FromBytes, B: FromBytes, C: FromBytes, D: FromBytes, E: FromBytes, F: FromBytes, G: FromBytes, H: FromBytes, I: FromBytes, J: FromBytes, K: FromBytes, L: FromBytes, M: FromBytes, N: FromBytes, O: FromBytes, P: FromBytes, Q: FromBytes, R: FromBytes, S: FromBytes, T: FromBytes, U: FromBytes, V: FromBytes> FromBytes 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: FromBytes, B: FromBytes, C: FromBytes, D: FromBytes, E: FromBytes, F: FromBytes, G: FromBytes, H: FromBytes, I: FromBytes, J: FromBytes, K: FromBytes, L: FromBytes, M: FromBytes, N: FromBytes, O: FromBytes, P: FromBytes, Q: FromBytes, R: FromBytes, S: FromBytes, T: FromBytes, U: FromBytes, V: FromBytes, W: FromBytes> FromBytes 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: FromBytes, B: FromBytes, C: FromBytes, D: FromBytes, E: FromBytes, F: FromBytes, G: FromBytes, H: FromBytes, I: FromBytes, J: FromBytes, K: FromBytes, L: FromBytes, M: FromBytes, N: FromBytes, O: FromBytes, P: FromBytes, Q: FromBytes, R: FromBytes, S: FromBytes, T: FromBytes, U: FromBytes, V: FromBytes, W: FromBytes, X: FromBytes> FromBytes 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: FromBytes, B: FromBytes, C: FromBytes, D: FromBytes, E: FromBytes, F: FromBytes, G: FromBytes, H: FromBytes, I: FromBytes, J: FromBytes, K: FromBytes, L: FromBytes, M: FromBytes, N: FromBytes, O: FromBytes, P: FromBytes, Q: FromBytes, R: FromBytes, S: FromBytes, T: FromBytes, U: FromBytes, V: FromBytes, W: FromBytes, X: FromBytes, Y: FromBytes> FromBytes 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: FromBytes, B: FromBytes, C: FromBytes, D: FromBytes, E: FromBytes, F: FromBytes, G: FromBytes, H: FromBytes, I: FromBytes, J: FromBytes, K: FromBytes, L: FromBytes, M: FromBytes, N: FromBytes, O: FromBytes, P: FromBytes, Q: FromBytes, R: FromBytes, S: FromBytes, T: FromBytes, U: FromBytes, V: FromBytes, W: FromBytes, X: FromBytes, Y: FromBytes, Z: FromBytes> FromBytes 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<T> FromBytes for CoreMaybeUninit<T>

Source§

impl<T: FromBytes> FromBytes for [T]

Source§

impl<T: FromBytes> FromBytes for Wrapping<T>

Source§

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

Source§

impl<T: ?Sized + FromBytes> FromBytes for Cell<T>

Source§

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

Source§

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

Source§

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

Implementors§

Source§

impl<O> FromBytes for F32<O>

Source§

impl<O> FromBytes for F64<O>

Source§

impl<O> FromBytes for I16<O>

Source§

impl<O> FromBytes for I32<O>

Source§

impl<O> FromBytes for I64<O>

Source§

impl<O> FromBytes for I128<O>

Source§

impl<O> FromBytes for Isize<O>

Source§

impl<O> FromBytes for U16<O>

Source§

impl<O> FromBytes for U32<O>

Source§

impl<O> FromBytes for U64<O>

Source§

impl<O> FromBytes for U128<O>

Source§

impl<O> FromBytes for Usize<O>

Source§

impl<T> FromBytes for Unalign<T>
where T: FromBytes,

Source§

impl<T: ?Sized + FromBytes> FromBytes for ReadOnly<T>