pub struct PrimitiveField<T: ?Sized, E: Endianness, const OFFSET_: usize> { /* private fields */ }
Expand description

A PrimitiveField is a Field that directly represents a primitive type like u8, i16, … See Field for more info on this API.

Example:

use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
  field_one: u16,
  another_field: [u8; 16],
  something_else: u32,
  tail_data: [u8],
});

fn func(storage_data: &mut [u8]) {
  // read some data
  let format_version_header: u16 = my_layout::field_one::read(storage_data);
  // equivalent: let format_version_header = u16::from_le_bytes((&storage_data[0..2]).try_into().unwrap());

  // write some data
  my_layout::something_else::write(storage_data, 10);
  // equivalent: data_slice[18..22].copy_from_slice(&10u32.to_le_bytes());

  // access a data region
  let tail_data: &[u8] = my_layout::tail_data::data(storage_data);
  // equivalent: let tail_data: &[u8] = &data_slice[22..];

  // and modify it
  my_layout::tail_data::data_mut(storage_data)[..5].copy_from_slice(&[1, 2, 3, 4, 5]);
  // equivalent: data_slice[18..22].copy_from_slice(&[1, 2, 3, 4, 5]);
}

Trait Implementations

‘Read’ the ()-typed field from a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_zst_field: ()
    //... other fields ...
});

fn func(storage_data: &[u8]) {
    let read: () = my_layout::some_zst_field::read(storage_data);
}

In reality, this method doesn’t do any work; () is a zero-sized type, so there’s no work to do. This implementation exists solely to make writing derive macros simpler.

‘Write’ the ()-typed field to a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_zst_field: ()
    //... other fields ...
});

fn func(storage_data: &mut [u8]) {
    my_layout::some_zst_field::write(storage_data, ());
}
WARNING

In reality, this method doesn’t do any work; () is a zero-sized type, so there’s no work to do. This implementation exists solely to make writing derive macros simpler.

Read the float field from a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_float_field: f32
    //... other fields ...
});

fn func(storage_data: &[u8]) {
    let read: f32 = my_layout::some_float_field::read(storage_data);
}
WARNING

At it’s core, this method uses f32::from_bits, which has some weird behavior around signaling and non-signaling NaN values. Read the documentation for f32::from_bits which explains the situation.

Write the float field to a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_float_field: f32
    //... other fields ...
});

fn func(storage_data: &mut [u8]) {
    my_layout::some_float_field::write(storage_data, 10.0);
}
WARNING

At it’s core, this method uses f32::to_bits, which has some weird behavior around signaling and non-signaling NaN values. Read the documentation for f32::to_bits which explains the situation.

Read the float field from a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_float_field: f64
    //... other fields ...
});

fn func(storage_data: &[u8]) {
    let read: f64 = my_layout::some_float_field::read(storage_data);
}
WARNING

At it’s core, this method uses f64::from_bits, which has some weird behavior around signaling and non-signaling NaN values. Read the documentation for f64::from_bits which explains the situation.

Write the float field to a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_float_field: f64
    //... other fields ...
});

fn func(storage_data: &mut [u8]) {
    my_layout::some_float_field::write(storage_data, 10.0);
}
WARNING

At it’s core, this method uses f64::to_bits, which has some weird behavior around signaling and non-signaling NaN values. Read the documentation for f64::to_bits which explains the situation.

Read the integer field from a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: i128
    //... other fields ...
});

fn func(storage_data: &[u8]) {
    let read: i128 = my_layout::some_integer_field::read(storage_data);
}

Write the integer field to a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: i128
    //... other fields ...
});

fn func(storage_data: &mut [u8]) {
    my_layout::some_integer_field::write(storage_data, 10);
}

Read the integer field from a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: i16
    //... other fields ...
});

fn func(storage_data: &[u8]) {
    let read: i16 = my_layout::some_integer_field::read(storage_data);
}

Write the integer field to a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: i16
    //... other fields ...
});

fn func(storage_data: &mut [u8]) {
    my_layout::some_integer_field::write(storage_data, 10);
}

Read the integer field from a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: i32
    //... other fields ...
});

fn func(storage_data: &[u8]) {
    let read: i32 = my_layout::some_integer_field::read(storage_data);
}

Write the integer field to a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: i32
    //... other fields ...
});

fn func(storage_data: &mut [u8]) {
    my_layout::some_integer_field::write(storage_data, 10);
}

Read the integer field from a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: i64
    //... other fields ...
});

fn func(storage_data: &[u8]) {
    let read: i64 = my_layout::some_integer_field::read(storage_data);
}

Write the integer field to a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: i64
    //... other fields ...
});

fn func(storage_data: &mut [u8]) {
    my_layout::some_integer_field::write(storage_data, 10);
}

Read the integer field from a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: i8
    //... other fields ...
});

fn func(storage_data: &[u8]) {
    let read: i8 = my_layout::some_integer_field::read(storage_data);
}

Write the integer field to a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: i8
    //... other fields ...
});

fn func(storage_data: &mut [u8]) {
    my_layout::some_integer_field::write(storage_data, 10);
}

Read the integer field from a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: u128
    //... other fields ...
});

fn func(storage_data: &[u8]) {
    let read: u128 = my_layout::some_integer_field::read(storage_data);
}

Write the integer field to a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: u128
    //... other fields ...
});

fn func(storage_data: &mut [u8]) {
    my_layout::some_integer_field::write(storage_data, 10);
}

Read the integer field from a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: u16
    //... other fields ...
});

fn func(storage_data: &[u8]) {
    let read: u16 = my_layout::some_integer_field::read(storage_data);
}

Write the integer field to a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: u16
    //... other fields ...
});

fn func(storage_data: &mut [u8]) {
    my_layout::some_integer_field::write(storage_data, 10);
}

Read the integer field from a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: u32
    //... other fields ...
});

fn func(storage_data: &[u8]) {
    let read: u32 = my_layout::some_integer_field::read(storage_data);
}

Write the integer field to a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: u32
    //... other fields ...
});

fn func(storage_data: &mut [u8]) {
    my_layout::some_integer_field::write(storage_data, 10);
}

Read the integer field from a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: u64
    //... other fields ...
});

fn func(storage_data: &[u8]) {
    let read: u64 = my_layout::some_integer_field::read(storage_data);
}

Write the integer field to a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: u64
    //... other fields ...
});

fn func(storage_data: &mut [u8]) {
    my_layout::some_integer_field::write(storage_data, 10);
}

Read the integer field from a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: u8
    //... other fields ...
});

fn func(storage_data: &[u8]) {
    let read: u8 = my_layout::some_integer_field::read(storage_data);
}

Write the integer field to a given data region, assuming the defined layout, using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_integer_field: u8
    //... other fields ...
});

fn func(storage_data: &mut [u8]) {
    my_layout::some_integer_field::write(storage_data, 10);
}

Field type [u8; N]: This field represents a fixed size byte array. In this impl, we define accessors for such fields.

Borrow the data in the byte array with read access using the Field API. See also FieldSliceAccess::data.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_field: [u8; 5],
    //... other fields
});

fn func(storage_data: &[u8]) {
    let some_field: &[u8; 5] = my_layout::some_field::data(storage_data);
}

Borrow the data in the byte array with write access using the Field API. See also FieldSliceAccess::data_mut

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    some_field: [u8; 5],
    //... other fields
});

fn func(storage_data: &mut [u8]) {
    let some_field: &mut [u8; 5] = my_layout::some_field::data_mut(storage_data);
}
The type of slice returned from calls requesting read access
The type of slice returned from calls requesting write access

Field type [u8]: This field represents an open ended byte array. In this impl, we define accessors for such fields.

Borrow the data in the byte array with read access using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    tail_data: [u8],
});

fn func(storage_data: &[u8]) {
    let tail_data: &[u8] = my_layout::tail_data::data(storage_data);
}

Borrow the data in the byte array with write access using the Field API.

Example:
use binary_layout::prelude::*;

define_layout!(my_layout, LittleEndian, {
    //... other fields ...
    tail_data: [u8],
});

fn func(storage_data: &mut [u8]) {
    let tail_data: &mut [u8] = my_layout::tail_data::data_mut(storage_data);
}
The type of slice returned from calls requesting read access
The type of slice returned from calls requesting write access

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.