pub use attribute::Attribute;
use attribute::Callback;
pub use element::Element;
use std::fmt;
pub(crate) mod attribute;
mod element;
#[derive(Clone, PartialEq)]
pub enum Node<NS, TAG, ATT, VAL, EVENT, MSG> {
Element(Element<NS, TAG, ATT, VAL, EVENT, MSG>),
Text(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_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),
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
}
}
}
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(),
}
}
}
#[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)
}
#[inline]
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>>,
) -> Node<NS, TAG, ATT, VAL, EVENT, MSG> {
Node::Element(Element::new(namespace, tag, attrs, children))
}
#[inline]
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(s.to_string())
}