Skip to main content

WrappedField

Struct WrappedField 

Source
pub struct WrappedField<U, T: LayoutAs<U>, F: Field> { /* private fields */ }
Expand description

A WrappedField is a Field that, unlike PrimitiveField, does not directly represent a primitive type. Instead, it represents a wrapper type that can be converted to/from a primitive type using the LayoutAs trait. See Field for more info on this API.

§Example (reading/writing cannot throw errors):

use binary_layout::{prelude::*, LayoutAs};
use core::convert::Infallible;

struct MyIdType(u64);
impl LayoutAs<u64> for MyIdType {
  type ReadError = Infallible;
  type WriteError = Infallible;

  fn try_read(v: u64) -> Result<MyIdType, Infallible> {
    Ok(MyIdType(v))
  }

  fn try_write(v: MyIdType) -> Result<u64, Infallible> {
    Ok(v.0)
  }
}

binary_layout!(my_layout, BigEndian, {
  // ... other fields ...
  field: MyIdType as u64,
  // ... other fields ...
});

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

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

§Example (reading/writing can throw errors):

use binary_layout::{prelude::*, WrappedFieldError, LayoutAs};
use core::convert::Infallible;

struct MyIdType(u64);
impl LayoutAs<u64> for MyIdType {
  type ReadError = &'static str;
  type WriteError = &'static str;

  fn try_read(v: u64) -> Result<MyIdType, &'static str> {
    Ok(MyIdType(v))
  }

  fn try_write(v: MyIdType) -> Result<u64, &'static str> {
    Ok(v.0)
  }
}

binary_layout!(my_layout, BigEndian, {
  // ... other fields ...
  field: MyIdType as u64,
  // ... other fields ...
});

fn func(storage_data: &mut [u8]) -> Result<(), WrappedFieldError<Infallible, &'static str>> {
  // read some data
  let read_data: MyIdType = my_layout::field::try_read(storage_data)?;
  // equivalent: let read_data = MyIdType(u16::from_le_bytes((&storage_data[0..2]).try_into().unwrap()));

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

  Ok(())
}

Trait Implementations§

Source§

impl<U, T: LayoutAs<U>, F: Field> Field for WrappedField<U, T, F>

Source§

const OFFSET: usize = F::OFFSET

Source§

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

Source§

type Endian = <F as Field>::Endian

Source§

impl<U, T: LayoutAs<U>, F: FieldCopyAccess<HighLevelType = U>> FieldCopyAccess for WrappedField<U, T, F>

Source§

type ReadError = WrappedFieldError<<F as FieldCopyAccess>::ReadError, <T as LayoutAs<U>>::ReadError>

Source§

type WriteError = WrappedFieldError<<F as FieldCopyAccess>::WriteError, <T as LayoutAs<U>>::WriteError>

Source§

type HighLevelType = T

Source§

fn try_read(storage: &[u8]) -> Result<Self::HighLevelType, Self::ReadError>

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

§Example:
use binary_layout::{prelude::*, LayoutAs};
use core::convert::Infallible;

#[derive(Debug, PartialEq, Eq)]
struct MyIdType(u64);
impl LayoutAs<u64> for MyIdType {
  type ReadError = Infallible;
  type WriteError = Infallible;

  fn try_read(v: u64) -> Result<MyIdType, Infallible> {
    Ok(MyIdType(v))
  }

  fn try_write(v: MyIdType) -> Result<u64, Infallible> {
    Ok(v.0)
  }
}

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

fn func(storage_data: &mut [u8]) {
  my_layout::some_integer_field::write(storage_data, MyIdType(50));
  assert_eq!(MyIdType(50), my_layout::some_integer_field::read(storage_data));
}
Source§

fn try_write( storage: &mut [u8], v: Self::HighLevelType, ) -> Result<(), Self::WriteError>

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

§Example:

See FieldCopyAccess::try_read for an example

Auto Trait Implementations§

§

impl<U, T, F> Freeze for WrappedField<U, T, F>

§

impl<U, T, F> RefUnwindSafe for WrappedField<U, T, F>

§

impl<U, T, F> Send for WrappedField<U, T, F>

§

impl<U, T, F> Sync for WrappedField<U, T, F>

§

impl<U, T, F> Unpin for WrappedField<U, T, F>

§

impl<U, T, F> UnsafeUnpin for WrappedField<U, T, F>

§

impl<U, T, F> UnwindSafe for WrappedField<U, T, F>

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<F> FieldReadExt for F
where F: FieldCopyAccess, <F as FieldCopyAccess>::ReadError: IsInfallible,

Source§

fn read(storage: &[u8]) -> <F as FieldReadExt>::HighLevelType

This implements a convenience method for reading any data type whose FieldCopyAccess::try_read does not throw errors. See FieldCopyAccess::try_read.

Source§

type HighLevelType = <F as FieldCopyAccess>::HighLevelType

The data type that is returned from read calls and has to be passed in to write calls. This can be different from the primitive type used in the binary blob, since that primitive type can be wrapped (see WrappedField ) into a high level type before being returned from read calls (or vice versa unwrapped when writing).
Source§

impl<F> FieldWriteExt for F
where F: FieldCopyAccess, <F as FieldCopyAccess>::WriteError: IsInfallible,

Source§

fn write(storage: &mut [u8], value: <F as FieldWriteExt>::HighLevelType)

This implements a convenience method for writing any data type whose FieldCopyAccess::try_write does not throw errors. See FieldCopyAccess::try_write.

Source§

type HighLevelType = <F as FieldCopyAccess>::HighLevelType

The data type that is returned from read calls and has to be passed in to write calls. This can be different from the primitive type used in the binary blob, since that primitive type can be wrapped (see WrappedField ) into a high level type before being returned from read calls (or vice versa unwrapped when writing).
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where 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 T
where U: Into<T>,

Source§

type Error = !

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 T
where U: TryFrom<T>,

Source§

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.