use afia_component_sys::{node_type, parent_node};
use crate::dom::element::DomElement;
use crate::ComponentImports;
pub struct DomNode {
handle: i64,
imports: ComponentImports,
}
pub trait AsDomNode: impls::Sealed {
#[doc(hidden)]
fn handle(&self) -> i64;
#[doc(hidden)]
fn imports(&self) -> &ComponentImports;
#[doc(hidden)]
fn imports_ptr(&self) -> *const std::ffi::c_void {
self.imports().component_imports_ptr
}
fn to_dom_node(&self) -> DomNode {
DomNode {
handle: self.handle(),
imports: self.imports().clone(),
}
}
fn node_type(&self) -> NodeType {
let node_type = unsafe { node_type(self.imports_ptr(), self.handle()) };
NodeType::from(node_type)
}
fn parent_node(&self) -> Option<DomNode> {
let parent = unsafe { parent_node(self.imports_ptr(), self.handle()) };
maybe_node(self.imports(), parent)
}
}
#[allow(missing_docs)]
pub enum NodeType {
Element = 1,
Text = 3,
}
impl From<i32> for NodeType {
fn from(value: i32) -> Self {
match value {
1 => Self::Element,
3 => Self::Text,
_ => unimplemented!(),
}
}
}
impl DomNode {
pub(crate) fn new_maybe(imports: &ComponentImports, node_handle: i64) -> Option<DomNode> {
maybe_node(imports, node_handle)
}
pub fn to_element(&self) -> Option<DomElement> {
if matches!(self.node_type(), NodeType::Element) {
let elem = DomElement::maybe_new(self.handle, self.imports.clone()).unwrap();
Some(elem)
} else {
None
}
}
}
fn maybe_node(imports: &ComponentImports, node_handle: i64) -> Option<DomNode> {
if node_handle == 0 {
None
} else {
Some(DomNode {
imports: imports.clone(),
handle: node_handle,
})
}
}
mod impls {
use super::*;
use crate::dom::element::DomElement;
use crate::dom::text::DomText;
pub trait Sealed {}
impl AsDomNode for DomNode {
fn handle(&self) -> i64 {
self.handle
}
fn imports(&self) -> &ComponentImports {
&self.imports
}
}
impl Sealed for DomNode {}
impl AsDomNode for DomElement {
fn handle(&self) -> i64 {
self.to_i64()
}
fn imports(&self) -> &ComponentImports {
self.component_imports()
}
}
impl Sealed for DomElement {}
impl AsDomNode for DomText {
fn handle(&self) -> i64 {
self.to_i64()
}
fn imports(&self) -> &ComponentImports {
self.component_imports()
}
}
impl Sealed for DomText {}
}