use processors::{DomNodes, DomNodeProcessor, Listeners, EmptyListeners};
use KeyValue;
use opt_std::marker::PhantomData;
pub trait DomNode<Message>: DomNodes<Message> + Sized {
type Children: DomNodes<Message>;
type Listeners: Listeners<Message>;
type WithoutListeners:
DomNode<
Message,
Children=Self::Children,
Listeners=EmptyListeners
>;
fn key(&self) -> Option<u32>;
fn with_key(self, key: usize) -> WithKey<Message, Self> {
assert!(self.key() == None, "Attempted to add multiple keys to a DomNode");
WithKey(self, key as u32, PhantomData)
}
#[cfg(feature = "use_std")]
fn displayable(&self) -> ::html_writer::HtmlDisplayable<Message, Self> {
::html_writer::HtmlDisplayable(self, PhantomData)
}
fn get_attribute(&self, _index: usize) -> Option<&KeyValue>;
fn attributes(&self) -> AttributeIter<Message, Self> {
AttributeIter { node: self, index: 0, _marker: PhantomData }
}
fn with_attributes<A: AsRef<[KeyValue]>>(self, attributes: A) -> WithAttributes<Message, Self, A> {
WithAttributes { node: self, attributes: attributes, _marker: PhantomData }
}
fn with_listeners<L: Listeners<Message>>(self, listeners: L) ->
WithListeners<Message, Self::WithoutListeners, (L, Self::Listeners)> {
let (without_listeners, old_listeners) = self.split_listeners();
WithListeners {
node: without_listeners,
listeners: (listeners, old_listeners),
_marker: PhantomData,
}
}
fn children(&self) -> &Self::Children;
fn listeners(&self) -> &Self::Listeners;
fn children_and_listeners(&self) -> (&Self::Children, &Self::Listeners);
fn split_listeners(self) -> (Self::WithoutListeners, Self::Listeners);
fn value(&self) -> DomValue;
#[cfg(any(feature = "use_std", test))]
fn write_html<W: ::std::io::Write>(&self, writer: &mut W) -> ::std::io::Result<()> {
use html_writer::HtmlWriter;
self.process_all::<HtmlWriter<W>>(writer)
}
}
pub enum DomValue<'a> {
Element {
tag: &'static str
},
Text(&'a str),
}
pub struct WithKey<M, T: DomNode<M>>(T, u32, PhantomData<M>);
impl<M, T: DomNode<M>> DomNodes<M> for WithKey<M, T> {
fn process_all<'a, P: DomNodeProcessor<'a, M>>(&'a self, acc: &mut P::Acc) -> Result<(), P::Error> {
P::get_processor()(acc, self)
}
}
impl<M, T: DomNode<M>> DomNode<M> for WithKey<M, T> {
type Children = T::Children;
type Listeners = T::Listeners;
type WithoutListeners = WithKey<M, T::WithoutListeners>;
fn key(&self) -> Option<u32> { Some(self.1) }
fn get_attribute(&self, index: usize) -> Option<&KeyValue> {
self.0.get_attribute(index)
}
fn children(&self) -> &Self::Children {
self.0.children()
}
fn listeners(&self) -> &Self::Listeners {
self.0.listeners()
}
fn children_and_listeners(&self) -> (&Self::Children, &Self::Listeners) {
self.0.children_and_listeners()
}
fn split_listeners(self) -> (Self::WithoutListeners, Self::Listeners) {
let (node, listeners) = self.0.split_listeners();
(WithKey(node, self.1, PhantomData), listeners)
}
fn value(&self) -> DomValue { self.0.value() }
}
pub struct WithAttributes<M, T: DomNode<M>, A: AsRef<[KeyValue]>> {
node: T,
attributes: A,
_marker: PhantomData<M>
}
impl<M, T: DomNode<M>, A: AsRef<[KeyValue]>> DomNodes<M> for WithAttributes<M, T, A> {
fn process_all<'a, P: DomNodeProcessor<'a, M>>(&'a self, acc: &mut P::Acc) -> Result<(), P::Error> {
P::get_processor()(acc, self)
}
}
impl<M, T, A> DomNode<M> for WithAttributes<M, T, A> where T: DomNode<M>, A: AsRef<[KeyValue]> {
type Children = T::Children;
type Listeners = T::Listeners;
type WithoutListeners = WithAttributes<M, T::WithoutListeners, A>;
fn key(&self) -> Option<u32> { self.node.key() }
fn get_attribute(&self, index: usize) -> Option<&KeyValue> {
let attributes = self.attributes.as_ref();
attributes
.get(index)
.or_else(|| self.node.get_attribute(index - attributes.len()))
}
fn children(&self) -> &Self::Children {
self.node.children()
}
fn listeners(&self) -> &Self::Listeners {
self.node.listeners()
}
fn children_and_listeners(&self) -> (&Self::Children, &Self::Listeners) {
self.node.children_and_listeners()
}
fn split_listeners(self) -> (Self::WithoutListeners, Self::Listeners) {
let (node, listeners) = self.node.split_listeners();
(
WithAttributes {
node: node,
attributes: self.attributes,
_marker: PhantomData,
},
listeners
)
}
fn value(&self) -> DomValue { self.node.value() }
}
pub struct WithListeners<M, T: DomNode<M, Listeners=EmptyListeners>, L: Listeners<M>> {
node: T,
listeners: L,
_marker: PhantomData<M>,
}
impl<M, T: DomNode<M, Listeners=EmptyListeners>, L: Listeners<M>> DomNodes<M> for WithListeners<M, T, L> {
fn process_all<'a, P: DomNodeProcessor<'a, M>>(&'a self, acc: &mut P::Acc) -> Result<(), P::Error> {
P::get_processor()(acc, self)
}
}
impl<M, T, L> DomNode<M> for WithListeners<M, T, L>
where T: DomNode<M, Listeners=EmptyListeners>, L: Listeners<M>
{
type Children = T::Children;
type Listeners = L;
type WithoutListeners = T;
fn key(&self) -> Option<u32> { self.node.key() }
fn get_attribute(&self, index: usize) -> Option<&KeyValue> {
self.node.get_attribute(index)
}
fn children(&self) -> &Self::Children {
self.node.children()
}
fn listeners(&self) -> &Self::Listeners {
&self.listeners
}
fn children_and_listeners(&self) -> (&Self::Children, &Self::Listeners) {
(self.node.children(), &self.listeners)
}
fn split_listeners(self) -> (Self::WithoutListeners, Self::Listeners) {
(self.node, self.listeners)
}
fn value(&self) -> DomValue { self.node.value() }
}
pub struct AttributeIter<'a, M, T: DomNode<M> + 'a> {
node: &'a T,
index: usize,
_marker: PhantomData<M>,
}
impl<'a, M, T: DomNode<M>> Iterator for AttributeIter<'a, M, T> {
type Item = &'a KeyValue;
fn next(&mut self) -> Option<Self::Item> {
let res = self.node.get_attribute(self.index);
self.index += 1;
res
}
}
static EMPTY_NODES_REF: &'static () = &();
static EMPTY_LISTN_REF: &'static EmptyListeners = &EmptyListeners;
#[cfg(any(feature = "use_std", test))]
impl<M> DomNodes<M> for String {
fn process_all<'a, P: DomNodeProcessor<'a, M>>(&'a self, acc: &mut P::Acc) -> Result<(), P::Error> {
P::get_processor()(acc, self)
}
}
#[cfg(any(feature = "use_std", test))]
impl<M> DomNode<M> for String {
type Children = ();
type Listeners = EmptyListeners;
type WithoutListeners = String;
fn key(&self) -> Option<u32> { None }
fn get_attribute(&self, _index: usize) -> Option<&KeyValue> {
None
}
fn children(&self) -> &Self::Children {
EMPTY_NODES_REF
}
fn listeners(&self) -> &Self::Listeners {
EMPTY_LISTN_REF
}
fn children_and_listeners(&self) -> (&Self::Children, &Self::Listeners) {
(EMPTY_NODES_REF, EMPTY_LISTN_REF)
}
fn split_listeners(self) -> (Self::WithoutListeners, Self::Listeners) {
(self, EmptyListeners)
}
fn value(&self) -> DomValue { DomValue::Text(&self) }
}
impl<'b, M> DomNodes<M> for &'b str {
fn process_all<'a, P: DomNodeProcessor<'a, M>>(&'a self, acc: &mut P::Acc) -> Result<(), P::Error> {
P::get_processor()(acc, self)
}
}
impl<'a, M> DomNode<M> for &'a str {
type Children = ();
type Listeners = EmptyListeners;
type WithoutListeners = Self;
fn key(&self) -> Option<u32> { None }
fn get_attribute(&self, _index: usize) -> Option<&KeyValue> { None }
fn children(&self) -> &Self::Children {
EMPTY_NODES_REF
}
fn listeners(&self) -> &Self::Listeners {
EMPTY_LISTN_REF
}
fn children_and_listeners(&self) -> (&Self::Children, &Self::Listeners) {
(EMPTY_NODES_REF, EMPTY_LISTN_REF)
}
fn split_listeners(self) -> (Self::WithoutListeners, Self::Listeners) {
(self, EmptyListeners)
}
fn value(&self) -> DomValue { DomValue::Text(self) }
}