use crate::node::{
attribute::Callback,
Attribute,
Node,
};
use std::fmt;
#[derive(PartialEq, Default)]
pub struct Element<NS, TAG, ATT, VAL, EVENT, MSG> {
pub namespace: Option<NS>,
pub tag: TAG,
pub attrs: Vec<Attribute<NS, ATT, VAL, EVENT, MSG>>,
pub children: Vec<Node<NS, TAG, ATT, VAL, EVENT, MSG>>,
pub self_closing: bool,
}
impl<NS, TAG, ATT, VAL, EVENT, MSG> Element<NS, TAG, ATT, VAL, EVENT, MSG> {
pub fn new(
namespace: Option<NS>,
tag: TAG,
attrs: Vec<Attribute<NS, ATT, VAL, EVENT, MSG>>,
children: Vec<Node<NS, TAG, ATT, VAL, EVENT, MSG>>,
self_closing: bool,
) -> Self {
Element {
namespace,
tag,
attrs,
children,
self_closing,
}
}
pub fn add_attributes(
&mut self,
attrs: Vec<Attribute<NS, ATT, VAL, EVENT, MSG>>,
) {
self.attrs.extend(attrs)
}
pub fn add_children(
&mut self,
children: Vec<Node<NS, TAG, ATT, VAL, EVENT, MSG>>,
) {
self.children.extend(children);
}
pub fn get_children(&self) -> &[Node<NS, TAG, ATT, VAL, EVENT, MSG>] {
&self.children
}
pub fn children_mut(
&mut self,
) -> &mut [Node<NS, TAG, ATT, VAL, EVENT, MSG>] {
&mut self.children
}
pub fn take_children(self) -> Vec<Node<NS, TAG, ATT, VAL, EVENT, MSG>> {
self.children
}
pub fn get_attributes(&self) -> &[Attribute<NS, ATT, VAL, EVENT, MSG>] {
&self.attrs
}
pub fn take_attributes(self) -> Vec<Attribute<NS, ATT, VAL, EVENT, MSG>> {
self.attrs
}
pub fn namespace(&self) -> Option<&NS> {
self.namespace.as_ref()
}
pub fn tag(&self) -> &TAG {
&self.tag
}
pub fn take_tag(self) -> TAG {
self.tag
}
pub fn set_tag(&mut self, tag: TAG) {
self.tag = tag;
}
}
impl<NS, TAG, ATT, VAL, EVENT, MSG> Element<NS, TAG, ATT, VAL, EVENT, MSG>
where
ATT: PartialEq,
{
pub fn remove_attribute(&mut self, key: &ATT) {
self.attrs.retain(|att| att.name != *key)
}
pub fn set_attributes(
&mut self,
attrs: Vec<Attribute<NS, ATT, VAL, EVENT, MSG>>,
) {
attrs
.iter()
.for_each(|att| self.remove_attribute(&att.name));
self.add_attributes(attrs);
}
pub fn merge_attributes(
&mut self,
new_attrs: Vec<Attribute<NS, ATT, VAL, EVENT, MSG>>,
) {
for new_att in new_attrs {
if let Some(existing_attr) =
self.attrs.iter_mut().find(|att| att.name == new_att.name)
{
existing_attr.value.extend(new_att.value);
} else {
self.attrs.push(new_att);
}
}
}
pub fn get_attribute_value(&self, name: &ATT) -> Option<Vec<&VAL>> {
let result: Vec<&VAL> = self
.attrs
.iter()
.filter(|att| att.name == *name)
.flat_map(|att| att.get_plain())
.collect();
if result.is_empty() {
None
} else {
Some(result)
}
}
}
impl<NS, TAG, ATT, VAL, EVENT, MSG> Element<NS, TAG, ATT, VAL, EVENT, MSG>
where
EVENT: 'static,
MSG: 'static,
{
pub fn map_callback<MSG2>(
self,
cb: Callback<MSG, MSG2>,
) -> Element<NS, TAG, ATT, VAL, EVENT, MSG2>
where
MSG2: 'static,
{
Element {
namespace: self.namespace,
tag: self.tag,
attrs: self
.attrs
.into_iter()
.map(|attr| attr.map_callback(cb.clone()))
.collect(),
children: self
.children
.into_iter()
.map(|child| child.map_callback(cb.clone()))
.collect(),
self_closing: self.self_closing,
}
}
}
impl<NS, TAG, ATT, VAL, EVENT, MSG> fmt::Debug
for Element<NS, TAG, ATT, VAL, EVENT, MSG>
where
NS: fmt::Debug,
TAG: fmt::Debug,
ATT: fmt::Debug,
VAL: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Element")
.field("namespace", &self.namespace)
.field("tag", &self.tag)
.field("attrs", &self.attrs)
.field("children", &self.children)
.field("self_closing", &self.self_closing)
.finish()?;
Ok(())
}
}
impl<NS, TAG, ATT, VAL, EVENT, MSG> Clone
for Element<NS, TAG, ATT, VAL, EVENT, MSG>
where
NS: Clone,
TAG: Clone,
ATT: Clone,
VAL: Clone,
{
fn clone(&self) -> Self {
Element {
namespace: self.namespace.clone(),
tag: self.tag.clone(),
attrs: self.attrs.clone(),
children: self.children.clone(),
self_closing: self.self_closing,
}
}
}