use core::fmt::{self, Debug, Display, Formatter};
use core::ops::{BitOr, Shl};
use crate::Cells;
use crate::error::StandardError;
#[derive(Clone, Copy, Default, Eq, PartialEq)]
pub struct Reg<'a> {
pub address: Cells<'a>,
pub size: Cells<'a>,
}
impl<'a> Reg<'a> {
pub(crate) fn from_cells([address, size]: [Cells<'a>; 2]) -> Self {
Self { address, size }
}
pub fn address<T: Default + From<u32> + Shl<usize, Output = T> + BitOr<Output = T>>(
self,
) -> Result<T, StandardError> {
self.address.to_int()
}
pub fn size<T: Default + From<u32> + Shl<usize, Output = T> + BitOr<Output = T>>(
self,
) -> Result<T, StandardError> {
self.size.to_int()
}
}
impl Display for Reg<'_> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{} {}", self.address, self.size)
}
}
impl Debug for Reg<'_> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(
f,
"Reg {{ address: {}, size: {} }}",
self.address, self.size
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn format_reg() {
let address = [0x123_45678.into(), 0xabcd_0000.into()];
let size = [0x1122_3344.into()];
let reg = Reg {
address: Cells(&address),
size: Cells(&size),
};
assert_eq!(reg.to_string(), "0x12345678abcd0000 0x11223344");
}
#[test]
fn address_size() {
let address = [0x123_45678.into(), 0xabcd_0000.into()];
let size = [0x1122_3344.into()];
let reg = Reg {
address: Cells(&address),
size: Cells(&size),
};
assert_eq!(
reg.address::<u32>(),
Err(StandardError::TooManyCells { cells: 2 })
);
assert_eq!(reg.address::<u64>(), Ok(0x1234_5678_abcd_0000));
assert_eq!(reg.size::<u32>(), Ok(0x1122_3344));
assert_eq!(reg.size::<u64>(), Ok(0x1122_3344));
}
}