afia_component/dom/
node.rs1use afia_component_sys::{node_type, parent_node};
7
8use crate::dom::element::DomElement;
9use crate::ComponentImports;
10
11pub struct DomNode {
16 handle: i64,
17 imports: ComponentImports,
18}
19
20pub trait AsDomNode: impls::Sealed {
22 #[doc(hidden)]
23 fn handle(&self) -> i64;
24
25 #[doc(hidden)]
26 fn imports(&self) -> &ComponentImports;
27 #[doc(hidden)]
28 fn imports_ptr(&self) -> *const std::ffi::c_void {
29 self.imports().component_imports_ptr
30 }
31
32 fn to_dom_node(&self) -> DomNode {
34 DomNode {
35 handle: self.handle(),
36 imports: self.imports().clone(),
37 }
38 }
39
40 fn node_type(&self) -> NodeType {
42 let node_type = unsafe { node_type(self.imports_ptr(), self.handle()) };
43 NodeType::from(node_type)
44 }
45
46 fn parent_node(&self) -> Option<DomNode> {
48 let parent = unsafe { parent_node(self.imports_ptr(), self.handle()) };
49 maybe_node(self.imports(), parent)
50 }
51}
52
53#[allow(missing_docs)]
58pub enum NodeType {
59 Element = 1,
60 Text = 3,
61}
62
63impl From<i32> for NodeType {
64 fn from(value: i32) -> Self {
65 match value {
66 1 => Self::Element,
67 3 => Self::Text,
68 _ => unimplemented!(),
69 }
70 }
71}
72
73impl DomNode {
74 pub(crate) fn new_maybe(imports: &ComponentImports, node_handle: i64) -> Option<DomNode> {
75 maybe_node(imports, node_handle)
76 }
77
78 pub fn to_element(&self) -> Option<DomElement> {
80 if matches!(self.node_type(), NodeType::Element) {
81 let elem = DomElement::maybe_new(self.handle, self.imports.clone()).unwrap();
82 Some(elem)
83 } else {
84 None
85 }
86 }
87}
88
89fn maybe_node(imports: &ComponentImports, node_handle: i64) -> Option<DomNode> {
90 if node_handle == 0 {
91 None
92 } else {
93 Some(DomNode {
94 imports: imports.clone(),
95 handle: node_handle,
96 })
97 }
98}
99
100mod impls {
101 use super::*;
102 use crate::dom::element::DomElement;
103 use crate::dom::text::DomText;
104
105 pub trait Sealed {}
106
107 impl AsDomNode for DomNode {
108 fn handle(&self) -> i64 {
109 self.handle
110 }
111
112 fn imports(&self) -> &ComponentImports {
113 &self.imports
114 }
115 }
116 impl Sealed for DomNode {}
117
118 impl AsDomNode for DomElement {
119 fn handle(&self) -> i64 {
120 self.to_i64()
121 }
122
123 fn imports(&self) -> &ComponentImports {
124 self.component_imports()
125 }
126 }
127 impl Sealed for DomElement {}
128
129 impl AsDomNode for DomText {
130 fn handle(&self) -> i64 {
131 self.to_i64()
132 }
133
134 fn imports(&self) -> &ComponentImports {
135 self.component_imports()
136 }
137 }
138 impl Sealed for DomText {}
139}