#![warn(missing_docs)]
mod attribute;
mod element;
mod format;
use std::{
fmt::{self, Display},
iter::{FilterMap, FlatMap, Map},
};
pub use attribute::*;
pub use element::*;
pub use Event::*;
pub trait ElementData<E> {
fn add_to(self, element: &mut E);
}
impl<'a, E, D> ElementData<E> for D
where
E: Element<'a>,
D: Into<Node<'a>>,
{
fn add_to(self, elem: &mut E) {
elem.children_mut().push(self.into());
}
}
impl<'a, E, D> ElementData<E> for Vec<D>
where
E: Element<'a>,
D: ElementData<E>,
{
fn add_to(self, elem: &mut E) {
for child in self {
child.add_to(elem);
}
}
}
impl<'a, E, D, const N: usize> ElementData<E> for [D; N]
where
E: Element<'a>,
D: ElementData<E>,
{
fn add_to(self, elem: &mut E) {
for child in self {
child.add_to(elem);
}
}
}
impl<'a, E, D> ElementData<E> for Option<D>
where
E: Element<'a>,
D: ElementData<E>,
{
fn add_to(self, elem: &mut E) {
if let Some(child) = self {
child.add_to(elem);
}
}
}
macro_rules! tuple_element_data {
($($T:ident),*) => {
impl<Elem, $($T),*> ElementData<Elem> for ($($T,)*)
where
$($T: ElementData<Elem>),*
{
#[allow(non_snake_case, unused_variables)]
fn add_to(self, elem: &mut Elem) {
let ($($T,)*) = self;
$($T.add_to(elem);)*
}
}
};
}
tuple_element_data!();
tuple_element_data!(A);
tuple_element_data!(A, B);
tuple_element_data!(A, B, C);
tuple_element_data!(A, B, C, D);
tuple_element_data!(A, B, C, D, E);
tuple_element_data!(A, B, C, D, E, F);
tuple_element_data!(A, B, C, D, E, F, G);
tuple_element_data!(A, B, C, D, E, F, G, H);
tuple_element_data!(A, B, C, D, E, F, G, H, I);
tuple_element_data!(A, B, C, D, E, F, G, H, I, J);
tuple_element_data!(A, B, C, D, E, F, G, H, I, J, K);
tuple_element_data!(A, B, C, D, E, F, G, H, I, J, K, L);
tuple_element_data!(A, B, C, D, E, F, G, H, I, J, K, L, M);
tuple_element_data!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
tuple_element_data!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
tuple_element_data!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
tuple_element_data!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q);
tuple_element_data!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R);
tuple_element_data!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S);
tuple_element_data!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T);
impl<I, E, F> ElementData<E> for Map<I, F>
where
Map<I, F>: Iterator,
<Map<I, F> as Iterator>::Item: ElementData<E>,
{
fn add_to(self, elem: &mut E) {
for child in self {
child.add_to(elem);
}
}
}
impl<I, E, F> ElementData<E> for FilterMap<I, F>
where
FilterMap<I, F>: Iterator,
<FilterMap<I, F> as Iterator>::Item: ElementData<E>,
{
fn add_to(self, elem: &mut E) {
for child in self {
child.add_to(elem);
}
}
}
impl<I, E, U, F> ElementData<E> for FlatMap<I, U, F>
where
U: IntoIterator,
FlatMap<I, U, F>: Iterator,
<FlatMap<I, U, F> as Iterator>::Item: ElementData<E>,
{
fn add_to(self, elem: &mut E) {
for child in self {
child.add_to(elem);
}
}
}
#[derive(Debug, Clone)]
pub struct Page<'a>(pub element_structs::Html<'a>);
impl<'a> Display for Page<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "<!DOCTYPE html>")?;
write!(f, "{}", self.0)
}
}
impl<'a> element_structs::Html<'a> {
pub fn page(self) -> Page<'a> {
Page(self)
}
}