|
| 1 | +use super::{FallibleNode, Node}; |
| 2 | +use crate::parsing::{NoPanic, ParserWithMode}; |
| 3 | + |
| 4 | +/// [Devicetree 3.3. `/aliases` |
| 5 | +/// node](https://devicetree-specification.readthedocs.io/en/latest/chapter3-devicenodes.html#aliases-node) |
| 6 | +/// |
| 7 | +/// A devicetree may have an aliases node (`/aliases`) that defines one or more |
| 8 | +/// alias properties. The alias node shall be at the root of the devicetree and |
| 9 | +/// have the node name `/aliases`. |
| 10 | +/// |
| 11 | +/// Each property of the `/aliases` node defines an alias. The property name |
| 12 | +/// specifies the alias name. The property value specifies the full path to a |
| 13 | +/// node in the devicetree. For example, the property `serial0 = |
| 14 | +/// "/simple-bus@fe000000/serial@llc500"` defines the alias `serial0`. |
| 15 | +/// |
| 16 | +/// An alias value is a device path and is encoded as a string. The value |
| 17 | +/// represents the full path to a node, but the path does not need to refer to a |
| 18 | +/// leaf node. |
| 19 | +/// |
| 20 | +/// A client program may use an alias property name to refer to a full device |
| 21 | +/// path as all or part of its string value. A client program, when considering |
| 22 | +/// a string as a device path, shall detect and use the alias. |
| 23 | +/// |
| 24 | +/// ### Example |
| 25 | +/// |
| 26 | +/// ```norust |
| 27 | +/// aliases { |
| 28 | +/// serial0 = "/simple-bus@fe000000/serial@llc500"; |
| 29 | +/// ethernet0 = "/simple-bus@fe000000/ethernet@31c000"; |
| 30 | +/// }; |
| 31 | +/// ``` |
| 32 | +/// |
| 33 | +/// Given the alias `serial0`, a client program can look at the `/aliases` node |
| 34 | +/// and determine the alias refers to the device path |
| 35 | +/// `/simple-bus@fe000000/serial@llc500`. |
| 36 | +#[derive(Debug, Clone, Copy)] |
| 37 | +pub struct Aliases<'a, P: ParserWithMode<'a>> { |
| 38 | + pub(crate) node: FallibleNode<'a, P>, |
| 39 | +} |
| 40 | + |
| 41 | +impl<'a, P: ParserWithMode<'a>> Aliases<'a, P> { |
| 42 | + /// Attempt to resolve an alias to a node name. |
| 43 | + pub fn resolve_name(self, alias: &str) -> P::Output<Option<&'a str>> { |
| 44 | + P::to_output(crate::tryblock!({ |
| 45 | + self.node.properties()?.find(alias)?.map(|p| p.as_value().map_err(Into::into)).transpose() |
| 46 | + })) |
| 47 | + } |
| 48 | + |
| 49 | + /// Attempt resolve an alias to the aliased-to node. |
| 50 | + pub fn resolve(self, alias: &str) -> P::Output<Option<Node<'a, P>>> { |
| 51 | + P::to_output(crate::tryblock!({ |
| 52 | + let Some(path) = Aliases::<(_, NoPanic)> { node: self.node }.resolve_name(alias)? else { |
| 53 | + return Ok(None); |
| 54 | + }; |
| 55 | + |
| 56 | + self.node.make_root::<P::Parser>()?.find_node(path).map(|r| r.map(|n| n.alt())) |
| 57 | + })) |
| 58 | + } |
| 59 | +} |
0 commit comments