use super::super::{StorageIntoFieldView, StorageToFieldView};
use super::{Endianness, PrimitiveField};
use crate::utils::data::Data;
use crate::Field;
pub trait OwningNestedView<S>
where
S: AsRef<[u8]>,
{
type View;
fn into_view(storage: S) -> Self::View;
}
pub trait BorrowingNestedView<S> {
type View;
fn view(storage: S) -> Self::View;
}
pub trait NestedViewInfo {
const SIZE: Option<usize>;
}
impl<N: NestedViewInfo, E: Endianness, const OFFSET_: usize> Field
for PrimitiveField<N, E, OFFSET_>
{
type Endian = E;
const OFFSET: usize = OFFSET_;
const SIZE: Option<usize> = N::SIZE;
}
impl<'a, N: BorrowingNestedView<&'a [u8]>, E: Endianness, const OFFSET_: usize>
StorageToFieldView<&'a [u8]> for PrimitiveField<N, E, OFFSET_>
where
Self: Field,
{
type View = N::View;
#[inline(always)]
fn view(storage: &'a [u8]) -> Self::View {
if let Some(size) = Self::SIZE {
N::view(&storage[Self::OFFSET..(Self::OFFSET + size)])
} else {
N::view(&storage[Self::OFFSET..])
}
}
}
impl<'a, N: BorrowingNestedView<&'a mut [u8]>, E: Endianness, const OFFSET_: usize>
StorageToFieldView<&'a mut [u8]> for PrimitiveField<N, E, OFFSET_>
where
Self: Field,
{
type View = N::View;
#[inline(always)]
fn view(storage: &'a mut [u8]) -> Self::View {
if let Some(size) = Self::SIZE {
N::view(&mut storage[Self::OFFSET..(Self::OFFSET + size)])
} else {
N::view(&mut storage[Self::OFFSET..])
}
}
}
impl<S: AsRef<[u8]>, N: OwningNestedView<Data<S>>, E: Endianness, const OFFSET_: usize>
StorageIntoFieldView<S> for PrimitiveField<N, E, OFFSET_>
where
Self: Field,
{
type View = N::View;
#[inline(always)]
fn into_view(storage: S) -> Self::View {
if let Some(size) = Self::SIZE {
N::into_view(Data::from(storage).into_subregion(Self::OFFSET..(Self::OFFSET + size)))
} else {
N::into_view(Data::from(storage).into_subregion(Self::OFFSET..))
}
}
}