From 21854f052025f53b8ca31e9a5bf28738ae5f9810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ma=C4=87kowski?= Date: Tue, 7 Jul 2026 10:08:08 +0000 Subject: [PATCH 1/2] feat(model): add `DeviceTree::find_node` read-only lookup --- src/model.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/model.rs b/src/model.rs index 0a38d44..00e842b 100644 --- a/src/model.rs +++ b/src/model.rs @@ -23,6 +23,7 @@ use core::fmt::Display; pub use node::{DeviceTreeNode, DeviceTreeNodeBuilder}; pub use property::DeviceTreeProperty; +use crate::Node; use crate::fdt::Fdt; use crate::memreserve::MemoryReservation; @@ -89,6 +90,40 @@ impl DeviceTree { } } + /// Finds a node by its path and returns a reference to it. + /// + /// # Performance + /// + /// This method traverses the device tree, but since child lookup is a + /// constant-time operation, performance is linear in the number of path + /// segments. + /// + /// # Examples + /// + /// ``` + /// use dtoolkit::Node; + /// use dtoolkit::model::{DeviceTree, DeviceTreeNode}; + /// + /// let mut tree = DeviceTree::new(); + /// tree.root.add_child(DeviceTreeNode::new("child").unwrap()); + /// let child = tree.find_node("/child").unwrap(); + /// assert_eq!(child.name(), "child"); + /// ``` + #[must_use] + pub fn find_node(&self, path: &str) -> Option<&DeviceTreeNode> { + if !path.starts_with('/') { + return None; + } + let mut current_node = &self.root; + if path == "/" { + return Some(current_node); + } + for component in path.split('/').filter(|s| !s.is_empty()) { + current_node = current_node.child(component)?; + } + Some(current_node) + } + /// Finds a node by its path and returns a mutable reference to it. /// /// # Performance From fd77afa778f0100506503bab1295f0cff8042fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ma=C4=87kowski?= Date: Wed, 15 Jul 2026 13:32:43 +0000 Subject: [PATCH 2/2] feat(model): add DeviceTreeNode::add_child_mut --- src/model/node.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/model/node.rs b/src/model/node.rs index 06b571f..3b5b5c8 100644 --- a/src/model/node.rs +++ b/src/model/node.rs @@ -392,6 +392,36 @@ impl DeviceTreeNode { self.children.insert(child.name.clone(), child); } + /// Adds a child to this node, returning a reference to it. + /// + /// # Performance + /// + /// This is a constant-time operation. + /// + /// # Examples + /// + /// ``` + /// use dtoolkit::model::{DeviceTreeNode, DeviceTreeProperty}; + /// use dtoolkit::{Node, Property}; + /// + /// let mut node = DeviceTreeNode::new("my-node").unwrap(); + /// let mut child = node.add_child_mut(DeviceTreeNode::new("child").unwrap()); + /// child.add_property(DeviceTreeProperty::new("test", "value").unwrap()); + /// assert_eq!( + /// (&node) + /// .child("child") + /// .unwrap() + /// .property("test") + /// .unwrap() + /// .value(), + /// b"value" + /// ); + /// ``` + #[must_use] + pub fn add_child_mut(&mut self, child: DeviceTreeNode) -> &mut DeviceTreeNode { + self.children.entry(child.name.clone()).or_insert(child) + } + /// Removes a child from this node by its name. /// /// # Performance