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§

source§

impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<[u8], E, OFFSET_>

§

type Endian = E

source§

const OFFSET: usize = OFFSET_

source§

const SIZE: Option<usize> = None

source§

impl<E: Endianness, const N: usize, const OFFSET_: usize> Field for PrimitiveField<[u8; N], E, OFFSET_>

source§

impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<(), E, OFFSET_>

source§

impl<N: NestedViewInfo, E: Endianness, const OFFSET_: usize> Field for PrimitiveField<N, E, OFFSET_>

§

type Endian = E

source§

const OFFSET: usize = OFFSET_

source§

const SIZE: Option<usize> = N::SIZE

source§

impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<f32, E, OFFSET_>

source§

impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<f64, E, OFFSET_>

source§

impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<i128, E, OFFSET_>

source§

impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<i16, E, OFFSET_>

source§

impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<i32, E, OFFSET_>

source§

impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<i64, E, OFFSET_>

source§

impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<i8, E, OFFSET_>

source§

impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<u128, E, OFFSET_>

source§

impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<u16, E, OFFSET_>

source§

impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<u32, E, OFFSET_>

source§

impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<u64, E, OFFSET_>

source§

impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<u8, E, OFFSET_>

source§

impl<E: Endianness, const OFFSET_: usize> FieldCopyAccess for PrimitiveField<(), E, OFFSET_>

§

type HighLevelType = ()

source§

fn read(_storage: &[u8])

‘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.

source§

fn write(_storage: &mut [u8], _value: ())

‘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.

source§

impl<E: Endianness, const OFFSET_: usize> FieldCopyAccess for PrimitiveField<f32, E, OFFSET_>

§

type HighLevelType = f32

source§

fn read(storage: &[u8]) -> f32

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.

source§

fn write(storage: &mut [u8], value: f32)

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.

source§

impl<E: Endianness, const OFFSET_: usize> FieldCopyAccess for PrimitiveField<f64, E, OFFSET_>

§

type HighLevelType = f64

source§

fn read(storage: &[u8]) -> f64

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.

source§

fn write(storage: &mut [u8], value: f64)

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.

source§

impl<E: Endianness, const OFFSET_: usize> FieldCopyAccess for PrimitiveField<i128, E, OFFSET_>

§

type HighLevelType = i128

source§

fn read(storage: &[u8]) -> i128

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);
}
source§

fn write(storage: &mut [u8], value: i128)

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);
}
source§

impl<E: Endianness, const OFFSET_: usize> FieldCopyAccess for PrimitiveField<i16, E, OFFSET_>

§

type HighLevelType = i16

source§

fn read(storage: &[u8]) -> i16

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);
}
source§

fn write(storage: &mut [u8], value: i16)

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);
}
source§

impl<E: Endianness, const OFFSET_: usize> FieldCopyAccess for PrimitiveField<i32, E, OFFSET_>

§

type HighLevelType = i32

source§

fn read(storage: &[u8]) -> i32

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);
}
source§

fn write(storage: &mut [u8], value: i32)

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);
}
source§

impl<E: Endianness, const OFFSET_: usize> FieldCopyAccess for PrimitiveField<i64, E, OFFSET_>

§

type HighLevelType = i64

source§

fn read(storage: &[u8]) -> i64

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);
}
source§

fn write(storage: &mut [u8], value: i64)

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);
}
source§

impl<E: Endianness, const OFFSET_: usize> FieldCopyAccess for PrimitiveField<i8, E, OFFSET_>

§

type HighLevelType = i8

source§

fn read(storage: &[u8]) -> i8

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);
}
source§

fn write(storage: &mut [u8], value: i8)

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);
}
source§

impl<E: Endianness, const OFFSET_: usize> FieldCopyAccess for PrimitiveField<u128, E, OFFSET_>

§

type HighLevelType = u128

source§

fn read(storage: &[u8]) -> u128

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);
}
source§

fn write(storage: &mut [u8], value: u128)

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);
}
source§

impl<E: Endianness, const OFFSET_: usize> FieldCopyAccess for PrimitiveField<u16, E, OFFSET_>

§

type HighLevelType = u16

source§

fn read(storage: &[u8]) -> u16

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);
}
source§

fn write(storage: &mut [u8], value: u16)

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);
}
source§

impl<E: Endianness, const OFFSET_: usize> FieldCopyAccess for PrimitiveField<u32, E, OFFSET_>

§

type HighLevelType = u32

source§

fn read(storage: &[u8]) -> u32

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);
}
source§

fn write(storage: &mut [u8], value: u32)

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);
}
source§

impl<E: Endianness, const OFFSET_: usize> FieldCopyAccess for PrimitiveField<u64, E, OFFSET_>

§

type HighLevelType = u64

source§

fn read(storage: &[u8]) -> u64

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);
}
source§

fn write(storage: &mut [u8], value: u64)

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);
}
source§

impl<E: Endianness, const OFFSET_: usize> FieldCopyAccess for PrimitiveField<u8, E, OFFSET_>

§

type HighLevelType = u8

source§

fn read(storage: &[u8]) -> u8

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);
}
source§

fn write(storage: &mut [u8], value: u8)

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);
}
source§

impl<'a, E: Endianness, const OFFSET_: usize> FieldSliceAccess<'a> for PrimitiveField<[u8], E, OFFSET_>

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

source§

fn data(storage: &'a [u8]) -> &'a [u8]

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);
}
source§

fn data_mut(storage: &'a mut [u8]) -> &'a mut [u8]

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);
}
§

type SliceType = &'a [u8]

The type of slice returned from calls requesting read access
§

type MutSliceType = &'a mut [u8]

The type of slice returned from calls requesting write access
source§

impl<'a, E: Endianness, const N: usize, const OFFSET_: usize> FieldSliceAccess<'a> for PrimitiveField<[u8; N], E, OFFSET_>

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

source§

fn data(storage: &'a [u8]) -> &'a [u8; N]

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);
}
source§

fn data_mut(storage: &'a mut [u8]) -> &'a mut [u8; N]

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);
}
§

type SliceType = &'a [u8; N]

The type of slice returned from calls requesting read access
§

type MutSliceType = &'a mut [u8; N]

The type of slice returned from calls requesting write access

Auto Trait Implementations§

§

impl<T: ?Sized, E, const OFFSET_: usize> RefUnwindSafe for PrimitiveField<T, E, OFFSET_>where E: RefUnwindSafe, T: RefUnwindSafe,

§

impl<T: ?Sized, E, const OFFSET_: usize> Send for PrimitiveField<T, E, OFFSET_>where E: Send, T: Send,

§

impl<T: ?Sized, E, const OFFSET_: usize> Sync for PrimitiveField<T, E, OFFSET_>where E: Sync, T: Sync,

§

impl<T: ?Sized, E, const OFFSET_: usize> Unpin for PrimitiveField<T, E, OFFSET_>where E: Unpin, T: Unpin,

§

impl<T: ?Sized, E, const OFFSET_: usize> UnwindSafe for PrimitiveField<T, E, OFFSET_>where E: UnwindSafe, T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

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

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.