use core::ops::Deref;
use alloc::{
string::{String, ToString},
vec::Vec,
};
use fdt_raw::Phandle;
use super::NodeView;
use crate::{NodeGeneric, NodeGenericMut, Property, ViewMutOp, ViewOp};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct InterruptRef {
pub name: Option<String>,
pub interrupt_parent: Phandle,
pub cells: u32,
pub specifier: Vec<u32>,
}
impl InterruptRef {
pub fn with_name(
name: Option<String>,
interrupt_parent: Phandle,
cells: u32,
specifier: Vec<u32>,
) -> Self {
Self {
name,
interrupt_parent,
cells,
specifier,
}
}
}
#[derive(Clone, Copy)]
pub struct IntcNodeView<'a> {
pub(super) inner: NodeGeneric<'a>,
}
impl<'a> ViewOp<'a> for IntcNodeView<'a> {
fn as_view(&self) -> NodeView<'a> {
self.inner.as_view()
}
}
impl<'a> Deref for IntcNodeView<'a> {
type Target = NodeGeneric<'a>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<'a> IntcNodeView<'a> {
pub(crate) fn try_from_view(view: NodeView<'a>) -> Option<Self> {
if view.as_node().is_interrupt_controller() {
Some(Self {
inner: NodeGeneric { inner: view },
})
} else {
None
}
}
pub fn interrupt_cells(&self) -> Option<u32> {
self.as_view().as_node().interrupt_cells()
}
pub fn interrupt_address_cells(&self) -> Option<u32> {
self.as_view().as_node().address_cells()
}
pub fn is_interrupt_controller(&self) -> bool {
true
}
pub fn compatibles(&self) -> Vec<String> {
self.as_view()
.as_node()
.compatibles()
.map(|s| s.to_string())
.collect()
}
}
pub struct IntcNodeViewMut<'a> {
pub(super) inner: NodeGenericMut<'a>,
}
impl<'a> ViewOp<'a> for IntcNodeViewMut<'a> {
fn as_view(&self) -> NodeView<'a> {
self.inner.as_view()
}
}
impl<'a> ViewMutOp<'a> for IntcNodeViewMut<'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("interrupt-controller", Vec::new()));
s
}
}
impl<'a> Deref for IntcNodeViewMut<'a> {
type Target = NodeGenericMut<'a>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<'a> IntcNodeViewMut<'a> {
pub(crate) fn try_from_view(view: NodeView<'a>) -> Option<Self> {
if view.as_node().is_interrupt_controller() {
Some(Self {
inner: NodeGenericMut { inner: view },
})
} else {
None
}
}
}