libfdt_rs/
node.rs

1use crate::{Error, Fdt, FdtNodeIter, FdtProperty, FdtPropertyIter, Offset};
2
3use core::borrow::Borrow;
4use core::ffi::{CStr, c_char, c_int};
5use core::hash::{Hash, Hasher};
6
7#[cfg(feature = "std")]
8use std::string::{String, ToString};
9
10#[cfg(not(feature = "std"))]
11use alloc::string::{String, ToString};
12
13/// Node representation in an [`Fdt`].
14#[derive(Debug, Clone)]
15pub struct FdtNode<'fdt> {
16    pub(crate) fdt: &'fdt Fdt,
17    pub(crate) offset: Offset,
18    pub(crate) name: &'fdt CStr,
19}
20
21/// A node reference in an [`Fdt`].
22/// There are two possible references:
23///     - [`FdtNodeRef::Path`]: a full path to a node.
24///     - [`FdtNodeRef::Symbol`]: a symbol pointing to a node.
25#[derive(Debug)]
26pub enum FdtNodeRef {
27    Path(String),
28    Symbol(String),
29}
30
31impl<'fdt> PartialEq for FdtNode<'fdt> {
32    fn eq(&self, other: &Self) -> bool {
33        self.offset == other.offset
34    }
35}
36
37impl<'fdt> Eq for FdtNode<'fdt> {}
38
39impl<'fdt> Borrow<Offset> for FdtNode<'fdt> {
40    fn borrow(&self) -> &Offset {
41        &self.offset
42    }
43}
44
45impl<'fdt> Hash for FdtNode<'fdt> {
46    fn hash<H: Hasher>(&self, state: &mut H) {
47        self.offset.hash(state)
48    }
49}
50
51impl<'fdt> FdtNode<'fdt> {
52    /// Get the [`Fdt`] in which the node lives.
53    pub fn fdt(&self) -> &'fdt Fdt {
54        self.fdt
55    }
56
57    /// Get the offset in the [`Fdt`] of the node.
58    pub fn offset(&self) -> Offset {
59        self.offset
60    }
61
62    /// Get an iterator over the subnodes of the node.
63    pub fn subnodes_iter(&self) -> Result<FdtNodeIter<'fdt>, Error> {
64        FdtNodeIter::new(self)
65    }
66
67    /// Get an iterator over the properties of the node.
68    pub fn properties_iter(&self) -> Result<FdtPropertyIter<'fdt>, Error> {
69        FdtPropertyIter::new(self)
70    }
71
72    /// Get the name of the node.
73    pub fn name(&self) -> &str {
74        self.name.to_str().unwrap()
75    }
76
77    /// Get the path in the [`Fdt`] of the node.
78    pub fn path(&self) -> Result<String, Error> {
79        let mut str_buf: [c_char; 2048] = [0; 2048];
80
81        unsafe {
82            Error::parse(libfdt_sys::fdt_get_path(
83                self.fdt.fdt,
84                self.offset.0,
85                str_buf.as_mut_ptr(),
86                str_buf.len() as c_int,
87            ))?;
88        }
89
90        let c_str = unsafe { CStr::from_ptr(str_buf.as_ptr()) };
91        let s = c_str.to_str().unwrap();
92
93        Ok(s.to_string())
94    }
95
96    /// Get a property in the node given its name.
97    pub fn get_property(&self, property_name: &str) -> Result<FdtProperty<'fdt>, Error> {
98        self.fdt.get_property(self, property_name)
99    }
100}