use core::fmt::{self, Display, Formatter};
use core::ops::{BitOr, Shl};
use crate::Cells;
use crate::error::StandardError;
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Range<'a> {
pub child_bus_address: Cells<'a>,
pub parent_bus_address: Cells<'a>,
pub length: Cells<'a>,
}
impl<'a> Range<'a> {
pub(crate) fn from_cells(
[child_bus_address, parent_bus_address, length]: [Cells<'a>; 3],
) -> Self {
Self {
child_bus_address,
parent_bus_address,
length,
}
}
pub fn child_bus_address<
T: Default + From<u32> + Shl<usize, Output = T> + BitOr<Output = T>,
>(
&self,
) -> Result<T, StandardError> {
self.child_bus_address.to_int()
}
pub fn parent_bus_address<
T: Default + From<u32> + Shl<usize, Output = T> + BitOr<Output = T>,
>(
&self,
) -> Result<T, StandardError> {
self.parent_bus_address.to_int()
}
pub fn length<T: Default + From<u32> + Shl<usize, Output = T> + BitOr<Output = T>>(
&self,
) -> Result<T, StandardError> {
self.length.to_int()
}
}
impl Display for Range<'_> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(
f,
"{} {} {}",
self.child_bus_address, self.parent_bus_address, self.length
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn format_range() {
let child_bus_address = [0x0.into(), 0x4000.into()];
let parent_bus_address = [0xe000_0000.into()];
let length = [0x10_0000.into()];
let range = Range {
child_bus_address: Cells(&child_bus_address),
parent_bus_address: Cells(&parent_bus_address),
length: Cells(&length),
};
assert_eq!(
range.to_string(),
"0x0000000000004000 0xe0000000 0x00100000"
);
}
}