mod node;
mod property;
mod writer;
use alloc::vec::Vec;
use core::fmt::Display;
pub use node::{DeviceTreeNode, DeviceTreeNodeBuilder};
pub use property::DeviceTreeProperty;
use crate::error::FdtParseError;
use crate::fdt::Fdt;
use crate::memreserve::MemoryReservation;
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct DeviceTree {
pub root: DeviceTreeNode,
pub memory_reservations: Vec<MemoryReservation>,
}
impl DeviceTree {
#[must_use]
pub fn new() -> Self {
Self {
root: DeviceTreeNode::new("/"),
memory_reservations: Vec::new(),
}
}
pub fn from_fdt(fdt: &Fdt<'_>) -> Result<Self, FdtParseError> {
let root = DeviceTreeNode::try_from(fdt.root())?;
let memory_reservations: Vec<_> = fdt.memory_reservations().collect();
Ok(DeviceTree {
root,
memory_reservations,
})
}
pub fn find_node_mut(&mut self, path: &str) -> Option<&mut DeviceTreeNode> {
if !path.starts_with('/') {
return None;
}
let mut current_node = &mut self.root;
if path == "/" {
return Some(current_node);
}
for component in path.split('/').filter(|s| !s.is_empty()) {
match current_node.child_mut(component) {
Some(node) => current_node = node,
None => return None,
}
}
Some(current_node)
}
}
impl Default for DeviceTree {
fn default() -> Self {
Self::new()
}
}
impl Display for DeviceTree {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Fdt::new(&self.to_dtb())
.expect("DeviceTree::to_dtb() should always generate a valid FDT")
.fmt(f)
}
}