pub use attribute::Attribute;
use attribute::Callback;
pub use element::Element;
use std::fmt;
pub(crate) mod attribute;
mod element;
#[derive(PartialEq)]
pub enum Node<NS, TAG, ATT, VAL, EVENT, MSG> {
Element(Element<NS, TAG, ATT, VAL, EVENT, MSG>),
Text(Text),
}
#[derive(PartialEq, Default, Debug, Clone)]
pub struct Text {
pub text: String,
}
impl Text {
pub fn new(txt: impl ToString) -> Self {
Text {
text: txt.to_string(),
}
}
pub fn set_text(&mut self, txt: impl ToString) {
self.text = txt.to_string();
}
}
impl<NS, TAG, ATT, VAL, EVENT, MSG> Node<NS, TAG, ATT, VAL, EVENT, MSG> {
pub fn is_text(&self) -> bool {
match self {
Node::Element(_) => false,
Node::Text(_) => true,
}
}
pub fn take_element(
self,
) -> Option<Element<NS, TAG, ATT, VAL, EVENT, MSG>> {
match self {
Node::Element(element) => Some(element),
Node::Text(_) => None,
}
}
pub fn as_element_mut(
&mut self,
) -> Option<&mut Element<NS, TAG, ATT, VAL, EVENT, MSG>> {
match *self {
Node::Element(ref mut element) => Some(element),
Node::Text(_) => None,
}
}
pub fn as_element_ref(
&self,
) -> Option<&Element<NS, TAG, ATT, VAL, EVENT, MSG>> {
match *self {
Node::Element(ref element) => Some(element),
Node::Text(_) => None,
}
}
pub fn add_children(
mut self,
children: Vec<Node<NS, TAG, ATT, VAL, EVENT, MSG>>,
) -> Self {
if let Some(element) = self.as_element_mut() {
element.add_children(children);
}
self
}
pub fn add_children_ref_mut(
&mut self,
children: Vec<Node<NS, TAG, ATT, VAL, EVENT, MSG>>,
) {
if let Some(element) = self.as_element_mut() {
element.add_children(children);
}
}
pub fn add_attributes(
mut self,
attributes: Vec<Attribute<NS, ATT, VAL, EVENT, MSG>>,
) -> Self {
if let Some(elm) = self.as_element_mut() {
elm.add_attributes(attributes);
}
self
}
pub fn add_attributes_ref_mut(
&mut self,
attributes: Vec<Attribute<NS, ATT, VAL, EVENT, MSG>>,
) {
if let Some(elm) = self.as_element_mut() {
elm.add_attributes(attributes);
}
}
pub fn get_attributes(
&self,
) -> Option<&[Attribute<NS, ATT, VAL, EVENT, MSG>]> {
match *self {
Node::Element(ref element) => Some(element.get_attributes()),
Node::Text(_) => None,
}
}
pub fn tag(&self) -> Option<&TAG> {
if let Some(e) = self.as_element_ref() {
Some(&e.tag)
} else {
None
}
}
pub fn text(&self) -> Option<&str> {
match self {
Node::Text(t) => Some(&t.text),
Node::Element(_) => None,
}
}
pub fn get_children(
&self,
) -> Option<&[Node<NS, TAG, ATT, VAL, EVENT, MSG>]> {
if let Some(element) = self.as_element_ref() {
Some(element.get_children())
} else {
None
}
}
pub fn children_mut(
&mut self,
) -> Option<&mut [Node<NS, TAG, ATT, VAL, EVENT, MSG>]> {
if let Some(element) = self.as_element_mut() {
Some(element.children_mut())
} else {
None
}
}
pub fn node_count(&self) -> usize {
let mut current = 0;
self.node_count_recursive(&mut current);
current
}
fn node_count_recursive(&self, current: &mut usize) {
match self {
Node::Text(_) => *current += 1,
Node::Element(element) => {
*current += 1;
for child in element.children.iter() {
child.node_count_recursive(current);
}
}
}
}
}
impl<NS, TAG, ATT, VAL, EVENT, MSG> Node<NS, TAG, ATT, VAL, EVENT, MSG>
where
ATT: PartialEq,
{
pub fn set_attributes_ref_mut(
&mut self,
attributes: Vec<Attribute<NS, ATT, VAL, EVENT, MSG>>,
) {
if let Some(elm) = self.as_element_mut() {
elm.set_attributes(attributes);
}
}
pub fn merge_attributes(
mut self,
attributes: Vec<Attribute<NS, ATT, VAL, EVENT, MSG>>,
) -> Self {
if let Some(elm) = self.as_element_mut() {
elm.merge_attributes(attributes);
}
self
}
pub fn get_attribute_value(&self, name: &ATT) -> Option<Vec<&VAL>> {
if let Some(elm) = self.as_element_ref() {
elm.get_attribute_value(name)
} else {
None
}
}
}
impl<NS, TAG, ATT, VAL, EVENT, MSG> Node<NS, TAG, ATT, VAL, EVENT, MSG>
where
EVENT: 'static,
MSG: 'static,
{
pub fn map_msg<F, MSG2>(
self,
func: F,
) -> Node<NS, TAG, ATT, VAL, EVENT, MSG2>
where
F: Fn(MSG) -> MSG2 + 'static,
MSG2: 'static,
{
let cb = Callback::from(func);
self.map_callback(cb)
}
pub fn map_callback<MSG2>(
self,
cb: Callback<MSG, MSG2>,
) -> Node<NS, TAG, ATT, VAL, EVENT, MSG2>
where
MSG2: 'static,
{
match self {
Node::Element(element) => Node::Element(element.map_callback(cb)),
Node::Text(text) => Node::Text(text),
}
}
}
impl<NS, TAG, ATT, VAL, EVENT, MSG> fmt::Debug
for Node<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 {
match self {
Node::Element(element) => {
f.debug_tuple("Element").field(element).finish()
}
Node::Text(txt) => f.debug_tuple("Text").field(txt).finish(),
}
}
}
impl<NS, TAG, ATT, VAL, EVENT, MSG> Clone
for Node<NS, TAG, ATT, VAL, EVENT, MSG>
where
NS: Clone,
TAG: Clone,
ATT: Clone,
VAL: Clone,
{
fn clone(&self) -> Self {
match self {
Node::Element(element) => Node::Element(element.clone()),
Node::Text(txt) => Node::Text(txt.clone()),
}
}
}
#[inline]
pub fn element<NS, TAG, ATT, VAL, EVENT, MSG>(
tag: TAG,
attrs: Vec<Attribute<NS, ATT, VAL, EVENT, MSG>>,
children: Vec<Node<NS, TAG, ATT, VAL, EVENT, MSG>>,
) -> Node<NS, TAG, ATT, VAL, EVENT, MSG> {
element_ns(None, tag, attrs, children, false)
}
pub fn element_ns<NS, TAG, ATT, VAL, EVENT, MSG>(
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,
) -> Node<NS, TAG, ATT, VAL, EVENT, MSG> {
Node::Element(Element::new(namespace, tag, attrs, children, self_closing))
}
pub fn text<S, NS, TAG, ATT, VAL, EVENT, MSG>(
s: S,
) -> Node<NS, TAG, ATT, VAL, EVENT, MSG>
where
S: ToString,
ATT: Clone,
{
Node::Text(Text::new(s))
}