tl/parser/
handle.rs

1use crate::Node;
2
3use super::Parser;
4
5/// The inner type of a NodeHandle, used to represent an index into the tags table
6pub type InnerNodeHandle = u32;
7
8/// A detached, external handle to a HTML node, originally obtained from a [Parser]
9///
10/// It contains an identifier that uniquely identifies an HTML node.
11/// In particular, it is an index into the global HTML tag table managed by the [`Parser`].
12/// To get a [`Node`] out of a [`NodeHandle`], call `NodeHandle::get()`
13///
14/// A common way to model self referential/recursive graphs is to have one "global" vector
15/// of nodes, and store indices into the vector instead of references.
16/// In the case of tl, the "global" HTML tag vector is stored in the [`Parser`] and [`NodeHandle`] represents the index.
17/// Because [`NodeHandle`] is only an index and completely detached from anything, you need to pass a parser to `NodeHandle::get()`
18#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
19#[repr(transparent)]
20pub struct NodeHandle(InnerNodeHandle);
21
22impl NodeHandle {
23    /// Creates a new handle to the given node
24    #[inline]
25    pub fn new(node: InnerNodeHandle) -> Self {
26        NodeHandle(node)
27    }
28
29    /// Returns a reference to the node that is associated to this specific handle
30    ///
31    /// It is an error to pass in the wrong parser.
32    /// It will either return `None` if this index points outside of the nodes table,
33    /// or it will return the one it points to.
34    pub fn get<'p, 'buf>(&self, parser: &'p Parser<'buf>) -> Option<&'p Node<'buf>> {
35        parser.resolve_node_id(self.0)
36    }
37
38    /// Returns a mutable reference to the node that is associated to this specific handle
39    ///
40    /// It is an error to pass in the wrong parser.
41    /// It will either return `None` if this index points outside of the nodes table,
42    /// or it will return the one it points to.
43    pub fn get_mut<'p, 'buf>(&self, parser: &'p mut Parser<'buf>) -> Option<&'p mut Node<'buf>> {
44        parser.resolve_node_id_mut(self.0)
45    }
46
47    /// Returns the internal unique Node ID that maps to a specific node in the node table
48    #[inline]
49    pub fn get_inner(&self) -> InnerNodeHandle {
50        self.0
51    }
52}