use super::common::*;
pub const trait Set<Type, const OFFSET: u8, const SIZE: u8>
where Type: const CastFromUReg
{
const ASSERT_FLAG: () = { assert_flag::<Type>(OFFSET); };
const ASSERT_FIELD: () = { assert_field::<Type>(OFFSET, SIZE); };
const ASSERT_MASK: () = { assert_mask::<Type>(SIZE); };
const ASSERT_ARRAY: () = {};
fn read(&self) -> UReg;
fn read_at(&self, idx: usize) -> UReg;
}
impl<const OFFSET: u8, const SIZE: u8>
const Set<bool, OFFSET, SIZE> for u8 {
fn read(&self) -> UReg {
*self as UReg
}
fn read_at(&self, _idx: usize) -> UReg {
*self as UReg
}
}
impl<const OFFSET: u8, const SIZE: u8>
const Set<bool, OFFSET, SIZE> for u16 {
fn read(&self) -> UReg {
*self as UReg
}
fn read_at(&self, _idx: usize) -> UReg {
*self as UReg
}
}
impl<const OFFSET: u8, const SIZE: u8>
const Set<bool, OFFSET, SIZE> for u32 {
fn read(&self) -> UReg {
*self as UReg
}
fn read_at(&self, _idx: usize) -> UReg {
*self as UReg
}
}
impl<const OFFSET: u8, const SIZE: u8>
const Set<u8, OFFSET, SIZE> for u8 {
fn read(&self) -> UReg {
*self as UReg
}
fn read_at(&self, _idx: usize) -> UReg {
*self as UReg
}
}
impl<const OFFSET: u8, const SIZE: u8>
const Set<u16, OFFSET, SIZE> for u16 {
fn read(&self) -> UReg {
*self as UReg
}
fn read_at(&self, _idx: usize) -> UReg {
*self as UReg
}
}
impl<const OFFSET: u8, const SIZE: u8>
const Set<u32, OFFSET, SIZE> for u32 {
fn read(&self) -> UReg {
*self as UReg
}
fn read_at(&self, _idx: usize) -> UReg {
*self as UReg
}
}
impl<const OFFSET: u8, const SIZE: u8, const N: usize>
const Set<bool, OFFSET, SIZE> for [u8; N] {
const ASSERT_ARRAY: () = {
let required_bits = OFFSET + SIZE;
let available_bits = N * 8;
assert!(
required_bits as usize <= available_bits,
"Bitfield out of bounds for the provided array storage!"
);
};
fn read(&self) -> UReg {
<[u8; N] as Set<u8, OFFSET, SIZE>>::read_at(self, 0)
}
fn read_at(&self, idx: usize) -> UReg {
self[idx] as UReg
}
}
impl<const OFFSET: u8, const SIZE: u8, const N: usize>
const Set<u8, OFFSET, SIZE> for [u8; N] {
const ASSERT_ARRAY: () = {
let required_bits = OFFSET + SIZE;
let available_bits = N * 8;
assert!(
required_bits as usize <= available_bits,
"Bitfield out of bounds for the provided array storage!"
);
};
fn read(&self) -> UReg {
<[u8; N] as Set<u8, OFFSET, SIZE>>::read_at(self, 0)
}
fn read_at(&self, idx: usize) -> UReg {
self[idx] as UReg
}
}
impl<const OFFSET: u8, const SIZE: u8, const N: usize>
const Set<u16, OFFSET, SIZE> for [u8; N] {
const ASSERT_ARRAY: () = {
let required_bits = OFFSET + SIZE;
let available_bits = N * 8;
assert!(
required_bits as usize <= available_bits,
"Bitfield out of bounds for the provided array storage!"
);
};
fn read(&self) -> UReg {
<[u8; N] as Set<u16, OFFSET, SIZE>>::read_at(self, 0)
}
fn read_at(&self, idx: usize) -> UReg {
let b0 = self[idx] as u32;
let b1 = self[idx + 1] as u32;
b0 << 8 | b1
}
}
impl<const OFFSET: u8, const SIZE: u8, const N: usize>
const Set<u32, OFFSET, SIZE> for [u8; N] {
const ASSERT_ARRAY: () = {
let required_bits = OFFSET + SIZE;
let available_bits = N * 8;
assert!(
required_bits as usize <= available_bits,
"Bitfield out of bounds for the provided array storage!"
);
};
fn read(&self) -> u32 {
<[u8; N] as Set<u32, OFFSET, SIZE>>::read_at(self, 0)
}
fn read_at(&self, idx: usize) -> u32 {
let b0 = self[idx] as u32;
let b1 = self[idx + 1] as u32;
let b2 = self[idx + 2] as u32;
let b3 = self[idx + 3] as u32;
b0 << 24 | b1 << 16 | b2 << 8 | b3
}
}