dtb_walker/
path.rs

1use core::{fmt, str};
2
3/// 设备树节点路径。
4pub struct Path<'a> {
5    pub(crate) parent: Option<&'a Path<'a>>,
6    pub(crate) name: &'a [u8],
7}
8
9impl Path<'_> {
10    pub(crate) const ROOT: Self = Self {
11        parent: None,
12        name: &[],
13    };
14
15    /// 返回路径层数。定义根节点的子节点层数为 0。
16    #[inline]
17    pub fn level(&self) -> usize {
18        if let Some(parent) = self.parent {
19            parent.level() + 1
20        } else {
21            0
22        }
23    }
24
25    /// 返回路径最后一级的节点名。
26    #[inline]
27    pub fn last(&self) -> &[u8] {
28        self.name
29    }
30
31    /// 将路径字符串格式化到 `buf` 中。
32    ///
33    /// 如果返回 `Ok(n)`,表示字符串长度为 `n`(`n` 不大于 `buf.len()`)。
34    /// 如果返回 `Err(n)`,表示缓冲区长度无法存放整个字符串,实现保证 `n` 等于 `buf.len()`。
35    pub fn join(&self, buf: &mut [u8]) -> Result<usize, usize> {
36        let len = match self.parent {
37            Some(parent) => parent.join(buf)?,
38            None => return Ok(0),
39        };
40        match buf.len() - len {
41            0 => Err(buf.len()),
42            mut rest => {
43                buf[len] = b'/';
44                rest -= 1;
45                if self.name.len() > rest {
46                    buf[len + 1..].copy_from_slice(&self.name[..rest]);
47                    Err(buf.len())
48                } else {
49                    buf[len + 1..][..self.name.len()].copy_from_slice(self.name);
50                    Ok(len + self.name.len() + 1)
51                }
52            }
53        }
54    }
55}
56
57impl fmt::Display for Path<'_> {
58    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59        if let Some(parent) = self.parent {
60            parent.fmt(f)?;
61            '/'.fmt(f)?;
62            unsafe { str::from_utf8_unchecked(self.name) }.fmt(f)
63        } else {
64            Ok(())
65        }
66    }
67}