use core::ops::Deref;
use alloc::vec::Vec;
use fdt_raw::MemoryRegion;
use super::NodeView;
use crate::{NodeGeneric, NodeGenericMut, Property, ViewMutOp, ViewOp};
#[derive(Clone, Copy)]
pub struct MemoryNodeView<'a> {
pub(super) inner: NodeGeneric<'a>,
}
impl<'a> Deref for MemoryNodeView<'a> {
type Target = NodeGeneric<'a>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<'a> ViewOp<'a> for MemoryNodeView<'a> {
fn as_view(&self) -> NodeView<'a> {
self.inner.as_view()
}
}
impl<'a> MemoryNodeView<'a> {
pub(crate) fn try_from_view(view: NodeView<'a>) -> Option<Self> {
if view.as_node().is_memory() {
Some(Self {
inner: NodeGeneric { inner: view },
})
} else {
None
}
}
pub fn regions(&self) -> Vec<MemoryRegion> {
let regs = self.as_view().regs();
regs.into_iter()
.map(|r| MemoryRegion {
address: r.address, size: r.size.unwrap_or(0),
})
.collect()
}
pub fn total_size(&self) -> u64 {
self.regions().iter().map(|r| r.size).sum()
}
}
pub struct MemoryNodeViewMut<'a> {
pub(super) inner: NodeGenericMut<'a>,
}
impl<'a> Deref for MemoryNodeViewMut<'a> {
type Target = NodeGenericMut<'a>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<'a> ViewOp<'a> for MemoryNodeViewMut<'a> {
fn as_view(&self) -> NodeView<'a> {
self.inner.as_view()
}
}
impl<'a> ViewMutOp<'a> for MemoryNodeViewMut<'a> {
fn new(node: NodeGenericMut<'a>) -> Self {
let mut s = Self { inner: node };
let n = s.inner.inner.as_node_mut();
n.set_property(Property::new("device_type", b"memory\0".to_vec()));
s
}
}
impl<'a> MemoryNodeViewMut<'a> {
pub(crate) fn try_from_view(view: NodeView<'a>) -> Option<Self> {
if view.as_node().is_memory() {
Some(Self {
inner: NodeGenericMut { inner: view },
})
} else {
None
}
}
}