kuchikikiki/
node_data_ref.rs1use crate::tree::{Doctype, DocumentData, ElementData, Node, NodeRef};
2use std::cell::RefCell;
3use std::fmt;
4use std::ops::Deref;
5
6impl NodeRef {
7 #[inline]
9 pub fn into_element_ref(self) -> Option<NodeDataRef<ElementData>> {
10 NodeDataRef::new_opt(self, Node::as_element)
11 }
12
13 #[inline]
15 pub fn into_text_ref(self) -> Option<NodeDataRef<RefCell<String>>> {
16 NodeDataRef::new_opt(self, Node::as_text)
17 }
18
19 #[inline]
21 pub fn into_comment_ref(self) -> Option<NodeDataRef<RefCell<String>>> {
22 NodeDataRef::new_opt(self, Node::as_comment)
23 }
24
25 #[inline]
27 pub fn into_doctype_ref(self) -> Option<NodeDataRef<Doctype>> {
28 NodeDataRef::new_opt(self, Node::as_doctype)
29 }
30
31 #[inline]
33 pub fn into_document_ref(self) -> Option<NodeDataRef<DocumentData>> {
34 NodeDataRef::new_opt(self, Node::as_document)
35 }
36}
37
38#[derive(Eq)]
40pub struct NodeDataRef<T> {
41 _keep_alive: NodeRef,
42 _reference: *const T,
43}
44
45impl<T> NodeDataRef<T> {
46 #[inline]
48 pub fn new<F>(rc: NodeRef, f: F) -> NodeDataRef<T>
49 where
50 F: FnOnce(&Node) -> &T,
51 {
52 NodeDataRef {
53 _reference: f(&rc),
54 _keep_alive: rc,
55 }
56 }
57
58 #[inline]
60 pub fn new_opt<F>(rc: NodeRef, f: F) -> Option<NodeDataRef<T>>
61 where
62 F: FnOnce(&Node) -> Option<&T>,
63 {
64 f(&rc).map(|r| r as *const T).map(move |r| NodeDataRef {
65 _reference: r,
66 _keep_alive: rc,
67 })
68 }
69
70 #[inline]
72 pub fn as_node(&self) -> &NodeRef {
73 &self._keep_alive
74 }
75}
76
77impl<T> Deref for NodeDataRef<T> {
78 type Target = T;
79 #[inline]
80 fn deref(&self) -> &T {
81 unsafe { &*self._reference }
82 }
83}
84
85impl<T> PartialEq for NodeDataRef<T> {
87 #[inline]
88 fn eq(&self, other: &Self) -> bool {
89 self._keep_alive == other._keep_alive
90 }
91}
92
93impl<T> Clone for NodeDataRef<T> {
95 #[inline]
96 fn clone(&self) -> Self {
97 NodeDataRef {
98 _keep_alive: self._keep_alive.clone(),
99 _reference: self._reference,
100 }
101 }
102}
103
104impl<T: fmt::Debug> fmt::Debug for NodeDataRef<T> {
105 #[inline]
106 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
107 fmt::Debug::fmt(&**self, f)
108 }
109}
110
111impl NodeDataRef<ElementData> {
112 pub fn text_contents(&self) -> String {
114 self.as_node().text_contents()
115 }
116}