on 8f8add6 help sign in
dodrio/src/node.rs
111 lines 2.7 kB history raw
1use bumpalo::{Bump, BumpAllocSafe};
3/// A node is either a text node or an element.
4#[derive(Debug, Clone)]
5pub enum Node<'a> {
6 /// A text node.
7 Text(TextNode<'a>),
9 /// An element potentially with attributes and children.
10 Element(ElementNode<'a>),
13/// Text nodes are just a string of text. They cannot have attributes or
14/// children.
15#[derive(Debug, Clone)]
16pub struct TextNode<'a> {
17 pub(crate) text: &'a str,
20/// Elements have a tag name, zero or more attributes, and zero or more
21/// children.
22#[derive(Debug, Clone)]
23pub struct ElementNode<'a> {
24 pub(crate) tag_name: &'a str,
25 pub(crate) attributes: &'a [Attribute<'a>],
26 pub(crate) children: &'a [Node<'a>],
29#[derive(Clone, Debug)]
30pub struct Attribute<'a> {
31 pub name: &'a str,
32 pub value: &'a str,
35impl<'a> Node<'a> {
36 /// Is this node a text node?
37 pub fn is_text(&self) -> bool {
38 match self {
39 Node::Text(_) => true,
40 _ => false,
41 }
42 }
44 /// Is this node an element?
45 pub fn is_element(&self) -> bool {
46 match self {
47 Node::Element { .. } => true,
48 _ => false,
49 }
50 }
53impl<'a> TextNode<'a> {
54 /// Get this text node's text content.
55 pub fn text(&self) -> &'a str {
56 self.text
57 }
60impl<'a> ElementNode<'a> {
61 /// Get this element's tag name.
62 pub fn tag_name(&self) -> &'a str {
63 self.tag_name
64 }
66 /// Get this element's attributes.
67 pub fn attributes(&self) -> &'a [Attribute<'a>] {
68 self.attributes
69 }
71 /// Get this element's attributes.
72 pub fn children(&self) -> &'a [Node<'a>] {
73 self.children
74 }
77impl<'a> BumpAllocSafe for Node<'a> {}
78impl<'a> BumpAllocSafe for Attribute<'a> {}
80impl<'a> Node<'a> {
81 /// Construct a new text node with the given text.
82 #[inline]
83 pub fn text(text: &'a str) -> Node<'a> {
84 Node::Text(TextNode { text })
85 }
87 /// Construct a new element node with the given tag name and children.
88 #[inline]
89 pub fn element<Attributes, Children>(
90 bump: &'a Bump,
91 tag_name: &'a str,
92 attributes: Attributes,
93 children: Children,
94 ) -> Node<'a>
95 where
96 Attributes: 'a + BumpAllocSafe + AsRef<[Attribute<'a>]>,
97 Children: 'a + BumpAllocSafe + AsRef<[Node<'a>]>,
98 {
99 let children: &'a Children = bump.alloc(children);
100 let children: &'a [Node<'a>] = children.as_ref();
102 let attributes: &'a Attributes = bump.alloc(attributes);
103 let attributes: &'a [Attribute<'a>] = attributes.as_ref();
105 Node::Element(ElementNode {
106 tag_name,
107 attributes,
108 children,
109 })
110 }