use crate::arena::NodeId;
use crate::document::Document;
use crate::node::NodeKind;
#[derive(Debug, Clone, Copy)]
pub struct Handle<'a> {
doc: &'a Document,
node: Option<NodeId>,
}
impl<'a> Handle<'a> {
pub fn new(doc: &'a Document, node: NodeId) -> Self {
Self {
doc,
node: Some(node),
}
}
pub fn null(doc: &'a Document) -> Self {
Self { doc, node: None }
}
pub fn is_null(&self) -> bool {
self.node.is_none()
}
pub fn to_node(&self) -> Option<NodeId> {
self.node
}
pub fn to_element(&self) -> Option<NodeId> {
let id = self.node?;
let data = self.doc.arena.get(id)?;
match &data.kind {
NodeKind::Element(_) => Some(id),
_ => None,
}
}
pub fn text(&self) -> Option<&'a str> {
let id = self.to_element()?;
self.doc.get_text(id)
}
pub fn attribute(&self, name: &str) -> Option<&'a str> {
let id = self.to_element()?;
self.doc.attribute(id, name)
}
#[must_use]
pub fn parent(&self) -> Handle<'a> {
Handle {
doc: self.doc,
node: self.node.and_then(|id| self.doc.parent(id)),
}
}
#[must_use]
pub fn first_child(&self) -> Handle<'a> {
Handle {
doc: self.doc,
node: self.node.and_then(|id| self.doc.first_child(id)),
}
}
#[must_use]
pub fn last_child(&self) -> Handle<'a> {
Handle {
doc: self.doc,
node: self.node.and_then(|id| self.doc.last_child(id)),
}
}
#[must_use]
pub fn next_sibling(&self) -> Handle<'a> {
Handle {
doc: self.doc,
node: self.node.and_then(|id| self.doc.next_sibling(id)),
}
}
#[must_use]
pub fn prev_sibling(&self) -> Handle<'a> {
Handle {
doc: self.doc,
node: self.node.and_then(|id| self.doc.prev_sibling(id)),
}
}
#[must_use]
pub fn first_child_element(&self, name: Option<&str>) -> Handle<'a> {
Handle {
doc: self.doc,
node: self
.node
.and_then(|id| self.doc.first_child_element(id, name)),
}
}
#[must_use]
pub fn next_sibling_element(&self, name: Option<&str>) -> Handle<'a> {
Handle {
doc: self.doc,
node: self
.node
.and_then(|id| self.doc.next_sibling_element(id, name)),
}
}
}
#[derive(Debug)]
pub struct HandleMut<'a> {
doc: &'a mut Document,
node: Option<NodeId>,
}
impl<'a> HandleMut<'a> {
pub fn new(doc: &'a mut Document, node: NodeId) -> Self {
Self {
doc,
node: Some(node),
}
}
pub fn null(doc: &'a mut Document) -> Self {
Self { doc, node: None }
}
pub fn is_null(&self) -> bool {
self.node.is_none()
}
pub fn to_node(&self) -> Option<NodeId> {
self.node
}
pub fn to_element(&self) -> Option<NodeId> {
let id = self.node?;
let data = self.doc.arena.get(id)?;
match &data.kind {
NodeKind::Element(_) => Some(id),
_ => None,
}
}
pub fn text(&self) -> Option<&str> {
let id = self.to_element()?;
self.doc.get_text(id)
}
pub fn attribute(&self, name: &str) -> Option<&str> {
let id = self.to_element()?;
self.doc.attribute(id, name)
}
pub fn into_doc(self) -> &'a mut Document {
self.doc
}
#[must_use]
pub fn parent(self) -> HandleMut<'a> {
let node = self.node.and_then(|id| self.doc.parent(id));
HandleMut {
doc: self.doc,
node,
}
}
#[must_use]
pub fn first_child(self) -> HandleMut<'a> {
let node = self.node.and_then(|id| self.doc.first_child(id));
HandleMut {
doc: self.doc,
node,
}
}
#[must_use]
pub fn last_child(self) -> HandleMut<'a> {
let node = self.node.and_then(|id| self.doc.last_child(id));
HandleMut {
doc: self.doc,
node,
}
}
#[must_use]
pub fn next_sibling(self) -> HandleMut<'a> {
let node = self.node.and_then(|id| self.doc.next_sibling(id));
HandleMut {
doc: self.doc,
node,
}
}
#[must_use]
pub fn prev_sibling(self) -> HandleMut<'a> {
let node = self.node.and_then(|id| self.doc.prev_sibling(id));
HandleMut {
doc: self.doc,
node,
}
}
#[must_use]
pub fn first_child_element(self, name: Option<&str>) -> HandleMut<'a> {
let node = self
.node
.and_then(|id| self.doc.first_child_element(id, name));
HandleMut {
doc: self.doc,
node,
}
}
#[must_use]
pub fn next_sibling_element(self, name: Option<&str>) -> HandleMut<'a> {
let node = self
.node
.and_then(|id| self.doc.next_sibling_element(id, name));
HandleMut {
doc: self.doc,
node,
}
}
}