Skip to content

Commit c052830

Browse files
committed
Add traits for common methods on nodes and properties.
1 parent 8898527 commit c052830

File tree

15 files changed

+668
-577
lines changed

15 files changed

+668
-577
lines changed

src/fdt/mod.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ use zerocopy::byteorder::big_endian;
2727
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
2828

2929
pub use self::node::FdtNode;
30-
pub use self::property::{Cells, FdtProperty};
30+
pub use self::property::FdtProperty;
31+
use crate::Node;
3132
use crate::error::{FdtErrorKind, FdtParseError};
3233
use crate::memreserve::MemoryReservation;
3334

@@ -487,7 +488,9 @@ impl<'a> Fdt<'a> {
487488
/// # Examples
488489
///
489490
/// ```
490-
/// # use dtoolkit::fdt::Fdt;
491+
/// use dtoolkit::Node;
492+
/// use dtoolkit::fdt::Fdt;
493+
///
491494
/// # let dtb = include_bytes!("../../tests/dtb/test.dtb");
492495
/// let fdt = Fdt::new(dtb).unwrap();
493496
/// let root = fdt.root();
@@ -528,15 +531,19 @@ impl<'a> Fdt<'a> {
528531
/// # Examples
529532
///
530533
/// ```
531-
/// # use dtoolkit::fdt::Fdt;
534+
/// use dtoolkit::Node;
535+
/// use dtoolkit::fdt::Fdt;
536+
///
532537
/// # let dtb = include_bytes!("../../tests/dtb/test_traversal.dtb");
533538
/// let fdt = Fdt::new(dtb).unwrap();
534539
/// let node = fdt.find_node("/a/b/c").unwrap();
535540
/// assert_eq!(node.name(), "c");
536541
/// ```
537542
///
538543
/// ```
539-
/// # use dtoolkit::fdt::Fdt;
544+
/// use dtoolkit::Node;
545+
/// use dtoolkit::fdt::Fdt;
546+
///
540547
/// # let dtb = include_bytes!("../../tests/dtb/test_children.dtb");
541548
/// let fdt = Fdt::new(dtb).unwrap();
542549
/// let node = fdt.find_node("/child2").unwrap();

src/fdt/node.rs

Lines changed: 25 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use core::fmt::{self, Display, Formatter};
1212

1313
use super::{FDT_TAGSIZE, Fdt, FdtToken};
14+
use crate::Node;
1415
use crate::fdt::property::{FdtPropIter, FdtProperty};
1516
use crate::standard::AddressSpaceProperties;
1617

@@ -24,14 +25,8 @@ pub struct FdtNode<'a> {
2425
pub(crate) parent_address_space: AddressSpaceProperties,
2526
}
2627

27-
impl<'a> FdtNode<'a> {
28-
pub(crate) fn new(fdt: Fdt<'a>, offset: usize) -> Self {
29-
Self {
30-
fdt,
31-
offset,
32-
parent_address_space: AddressSpaceProperties::default(),
33-
}
34-
}
28+
impl<'a> Node<'a> for FdtNode<'a> {
29+
type Property = FdtProperty<'a>;
3530

3631
/// Returns the name of this node.
3732
///
@@ -44,71 +39,30 @@ impl<'a> FdtNode<'a> {
4439
/// # Examples
4540
///
4641
/// ```
47-
/// # use dtoolkit::fdt::Fdt;
42+
/// use dtoolkit::Node;
43+
/// use dtoolkit::fdt::Fdt;
44+
///
4845
/// # let dtb = include_bytes!("../../tests/dtb/test_children.dtb");
4946
/// let fdt = Fdt::new(dtb).unwrap();
5047
/// let root = fdt.root();
5148
/// let child = root.child("child1").unwrap();
5249
/// assert_eq!(child.name(), "child1");
5350
/// ```
54-
#[must_use]
55-
pub fn name(&self) -> &'a str {
51+
fn name(&self) -> &'a str {
5652
let name_offset = self.offset + FDT_TAGSIZE;
5753
self.fdt
5854
.string_at_offset(name_offset, None)
5955
.expect("Fdt should be valid")
6056
}
6157

62-
/// Returns the name of this node without the unit address, if any.
63-
///
64-
/// # Panics
65-
///
66-
/// Panics if the [`Fdt`] structure was constructed using
67-
/// [`Fdt::new_unchecked`] or [`Fdt::from_raw_unchecked`] and the FDT is not
68-
/// valid.
69-
#[must_use]
70-
pub fn name_without_address(&self) -> &'a str {
71-
let name = self.name();
72-
if let Some((name, _)) = name.split_once('@') {
73-
name
74-
} else {
75-
name
76-
}
77-
}
78-
79-
/// Returns a property by its name.
80-
///
81-
/// # Performance
82-
///
83-
/// This method iterates through all properties of the node.
84-
///
85-
/// # Examples
86-
///
87-
/// ```
88-
/// # use dtoolkit::fdt::Fdt;
89-
/// # let dtb = include_bytes!("../../tests/dtb/test_props.dtb");
90-
/// let fdt = Fdt::new(dtb).unwrap();
91-
/// let node = fdt.find_node("/test-props").unwrap();
92-
/// let prop = node.property("u32-prop").unwrap();
93-
/// assert_eq!(prop.name(), "u32-prop");
94-
/// ```
95-
///
96-
/// # Panics
97-
///
98-
/// Panics if the [`Fdt`] structure was constructed using
99-
/// [`Fdt::new_unchecked`] or [`Fdt::from_raw_unchecked`] and the FDT is not
100-
/// valid.
101-
#[must_use]
102-
pub fn property(&self, name: &str) -> Option<FdtProperty<'a>> {
103-
self.properties().find(|property| property.name() == name)
104-
}
105-
10658
/// Returns an iterator over the properties of this node.
10759
///
10860
/// # Examples
10961
///
11062
/// ```
111-
/// # use dtoolkit::fdt::Fdt;
63+
/// use dtoolkit::fdt::Fdt;
64+
/// use dtoolkit::{Node, Property};
65+
///
11266
/// # let dtb = include_bytes!("../../tests/dtb/test_props.dtb");
11367
/// let fdt = Fdt::new(dtb).unwrap();
11468
/// let node = fdt.find_node("/test-props").unwrap();
@@ -117,78 +71,21 @@ impl<'a> FdtNode<'a> {
11771
/// assert_eq!(props.next().unwrap().name(), "u64-prop");
11872
/// assert_eq!(props.next().unwrap().name(), "str-prop");
11973
/// ```
120-
pub fn properties(&self) -> impl Iterator<Item = FdtProperty<'a>> + use<'a> {
74+
fn properties(&self) -> impl Iterator<Item = FdtProperty<'a>> + use<'a> {
12175
FdtPropIter::Start {
12276
fdt: self.fdt,
12377
offset: self.offset,
12478
}
12579
}
12680

127-
/// Returns a child node by its name.
128-
///
129-
/// If the given name contains a _unit-address_ (the part after the `@`
130-
/// sign) then both the _node-name_ and _unit-address_ must match. If it
131-
/// doesn't have a _unit-address_, then nodes with any _unit-address_ or
132-
/// none will be allowed.
133-
///
134-
/// For example, searching for `memory` as a child of `/` would match either
135-
/// `/memory` or `/memory@4000`, while `memory@4000` would match only the
136-
/// latter.
137-
///
138-
/// # Performance
139-
///
140-
/// This method's performance is linear in the number of children of this
141-
/// node because it iterates through the children. If you need to call this
142-
/// often, consider converting to a
143-
/// [`DeviceTreeNode`](crate::model::DeviceTreeNode) first. Child lookup
144-
/// on a [`DeviceTreeNode`](crate::model::DeviceTreeNode) is a
145-
/// constant-time operation.
146-
///
147-
/// # Panics
148-
///
149-
/// Panics if the [`Fdt`] structure was constructed using
150-
/// [`Fdt::new_unchecked`] or [`Fdt::from_raw_unchecked`] and the FDT is not
151-
/// valid.
152-
///
153-
/// # Examples
154-
///
155-
/// ```
156-
/// # use dtoolkit::fdt::Fdt;
157-
/// # let dtb = include_bytes!("../../tests/dtb/test_children.dtb");
158-
/// let fdt = Fdt::new(dtb).unwrap();
159-
/// let root = fdt.root();
160-
/// let child = root.child("child1").unwrap();
161-
/// assert_eq!(child.name(), "child1");
162-
/// ```
163-
///
164-
/// ```
165-
/// # use dtoolkit::fdt::Fdt;
166-
/// # let dtb = include_bytes!("../../tests/dtb/test_children.dtb");
167-
/// let fdt = Fdt::new(dtb).unwrap();
168-
/// let root = fdt.root();
169-
/// let child = root.child("child2").unwrap();
170-
/// assert_eq!(child.name(), "child2@42");
171-
/// let child = root.child("child2@42").unwrap();
172-
/// assert_eq!(child.name(), "child2@42");
173-
/// ```
174-
#[must_use]
175-
pub fn child(&self, name: &str) -> Option<FdtNode<'a>> {
176-
let include_address = name.contains('@');
177-
self.children().find(|&child| {
178-
if include_address {
179-
child.name() == name
180-
} else {
181-
child.name_without_address() == name
182-
}
183-
})
184-
}
185-
18681
/// Returns an iterator over the children of this node.
18782
///
18883
/// # Examples
18984
///
19085
/// ```
191-
/// # use dtoolkit::fdt::Fdt;
86+
/// use dtoolkit::Node;
87+
/// use dtoolkit::fdt::Fdt;
88+
///
19289
/// # let dtb = include_bytes!("../../tests/dtb/test_children.dtb");
19390
/// let fdt = Fdt::new(dtb).unwrap();
19491
/// let root = fdt.root();
@@ -197,9 +94,19 @@ impl<'a> FdtNode<'a> {
19794
/// assert_eq!(children.next().unwrap().name(), "child2@42");
19895
/// assert!(children.next().is_none());
19996
/// ```
200-
pub fn children(&self) -> impl Iterator<Item = FdtNode<'a>> + use<'a> {
97+
fn children(&self) -> impl Iterator<Item = FdtNode<'a>> + use<'a> {
20198
FdtChildIter::Start { node: *self }
20299
}
100+
}
101+
102+
impl<'a> FdtNode<'a> {
103+
pub(crate) fn new(fdt: Fdt<'a>, offset: usize) -> Self {
104+
Self {
105+
fdt,
106+
offset,
107+
parent_address_space: AddressSpaceProperties::default(),
108+
}
109+
}
203110

204111
pub(crate) fn fmt_recursive(&self, f: &mut Formatter, indent: usize) -> fmt::Result {
205112
let name = self.name();

0 commit comments

Comments
 (0)