use std::{
any::type_name,
borrow::Cow,
ops::{Deref, DerefMut},
os::raw::c_void,
ptr::{NonNull, null_mut},
};
use crate::tree::{
InvalidNodePointerCastError, NodeCommon, XmlAttributeDefault, XmlAttributeType, XmlDocPtr,
XmlElementType, XmlGenericNodePtr,
};
use super::{XmlDtdPtr, XmlEnumeration};
#[repr(C)]
#[derive(Clone)]
pub struct XmlAttribute {
pub _private: *mut c_void,
pub(crate) typ: XmlElementType,
pub(crate) name: Option<String>,
pub(crate) children: Option<XmlGenericNodePtr>,
pub(crate) last: Option<XmlGenericNodePtr>,
pub(crate) parent: Option<XmlDtdPtr>,
pub(crate) next: Option<XmlGenericNodePtr>,
pub(crate) prev: Option<XmlGenericNodePtr>,
pub(crate) doc: Option<XmlDocPtr>,
pub(crate) nexth: Option<XmlAttributePtr>,
pub(crate) atype: XmlAttributeType,
pub(crate) def: XmlAttributeDefault,
pub(crate) default_value: Option<Box<str>>,
pub(crate) tree: Option<Box<XmlEnumeration>>,
pub(crate) prefix: Option<String>,
pub(crate) elem: Option<String>,
}
impl XmlAttribute {
pub(crate) fn get_prop_node_value_internal(&self) -> Option<String> {
self.default_value.as_deref().map(|def| def.to_owned())
}
}
impl Default for XmlAttribute {
fn default() -> Self {
Self {
_private: null_mut(),
typ: XmlElementType::XmlAttributeDecl,
name: None,
children: None,
last: None,
parent: None,
next: None,
prev: None,
doc: None,
nexth: None,
atype: XmlAttributeType::XmlAttributeCDATA,
def: XmlAttributeDefault::XmlAttributeNone,
default_value: None,
tree: None,
prefix: None,
elem: None,
}
}
}
impl NodeCommon for XmlAttribute {
fn document(&self) -> Option<XmlDocPtr> {
self.doc
}
fn set_document(&mut self, doc: Option<XmlDocPtr>) {
self.doc = doc;
}
fn element_type(&self) -> XmlElementType {
self.typ
}
fn name(&self) -> Option<Cow<'_, str>> {
self.name.as_deref().map(Cow::Borrowed)
}
fn children(&self) -> Option<XmlGenericNodePtr> {
self.children
}
fn set_children(&mut self, children: Option<XmlGenericNodePtr>) {
self.children = children;
}
fn last(&self) -> Option<XmlGenericNodePtr> {
self.last
}
fn set_last(&mut self, last: Option<XmlGenericNodePtr>) {
self.last = last;
}
fn next(&self) -> Option<XmlGenericNodePtr> {
self.next
}
fn set_next(&mut self, next: Option<XmlGenericNodePtr>) {
self.next = next;
}
fn prev(&self) -> Option<XmlGenericNodePtr> {
self.prev
}
fn set_prev(&mut self, prev: Option<XmlGenericNodePtr>) {
self.prev = prev;
}
fn parent(&self) -> Option<XmlGenericNodePtr> {
self.parent.map(|node| node.into())
}
fn set_parent(&mut self, parent: Option<XmlGenericNodePtr>) {
self.parent = parent.map(|p| XmlDtdPtr::try_from(p).unwrap());
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct XmlAttributePtr(NonNull<XmlAttribute>);
impl XmlAttributePtr {
pub(crate) fn new(node: XmlAttribute) -> Option<Self> {
let boxed = Box::new(node);
NonNull::new(Box::leak(boxed)).map(Self)
}
pub(crate) unsafe fn free(self) {
unsafe {
let _ = *Box::from_raw(self.0.as_ptr());
}
}
}
impl Clone for XmlAttributePtr {
fn clone(&self) -> Self {
*self
}
}
impl Copy for XmlAttributePtr {}
impl Deref for XmlAttributePtr {
type Target = XmlAttribute;
fn deref(&self) -> &Self::Target {
unsafe { self.0.as_ref() }
}
}
impl DerefMut for XmlAttributePtr {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.0.as_mut() }
}
}
impl TryFrom<XmlGenericNodePtr> for XmlAttributePtr {
type Error = InvalidNodePointerCastError;
fn try_from(value: XmlGenericNodePtr) -> Result<Self, Self::Error> {
match value.element_type() {
XmlElementType::XmlAttributeDecl => Ok(Self(value.0.cast())),
_ => Err(InvalidNodePointerCastError {
from: value.element_type(),
to: type_name::<Self>(),
}),
}
}
}
impl From<XmlAttributePtr> for XmlGenericNodePtr {
fn from(value: XmlAttributePtr) -> Self {
Self(value.0 as NonNull<dyn NodeCommon>)
}
}
impl From<XmlAttributePtr> for *mut XmlAttribute {
fn from(value: XmlAttributePtr) -> Self {
value.0.as_ptr()
}
}
#[doc(alias = "xmlFreeAttribute")]
pub(crate) unsafe fn xml_free_attribute(mut attr: XmlAttributePtr) {
unsafe {
attr.unlink();
attr.free();
}
}