1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
use crate::attributes; use crate::tag::Tag; use crate::text::Text; use attributes::Attribute; use derive_more::{From, Into}; use std::collections::HashMap; ///! A loose representation of the tree structure HTML follows ///! This can still be used to generate 'invalid' html. ///! Eg a br tag with children would be possible. However most browsers ///! are incredibly lax, as is HTML somewhat, so this is at least highly useable ///! If you know what tags you need ///! ///! This file attempts to be the full set of tools needed, so there is no usage ///! Of traits allowing further 'custom' types. It is more Data driven in it's approach ///! ///! Note: All datastructures here are fairly public, allowing them to be manipulated ///! as desired type Void = (); type Normal<'a> = Vec<Node<'a>>; type Attributes<'a> = HashMap<Attribute<'a>, Option<attributes::Value>>; /// Describes all potential shapes of a html element /// Note that there are only three kinds, text nodes, comment nodes, and element nodes /// but an element node can be void, or have children #[derive(Clone, From)] pub enum Node<'a> { Text(Text), Comment(Comment), Element(Element<'a, Normal<'a>>), Void(Element<'a, Void>), } /// A Html comment node. <!---- Text ---> #[derive(From, Into, Clone)] pub struct Comment(String); /// The html element type. This is the most common /// Note: if children is None, then it is handled as an empty /// element, this is different than having no children #[derive(Clone)] pub struct Element<'a, T> where T: ElementType, { pub name: Tag<'a>, pub attributes: Attributes<'a>, pub children: T, } /// Represents the different element types. /// Note: This is sealed so cannot be implemented other this crate /// Implementations pub trait ElementType: private::Sealed + Default {} mod private { impl super::ElementType for super::Void {} impl<'a> super::ElementType for super::Normal<'a> {} pub trait Sealed {} impl Sealed for () {} impl<'a> Sealed for Vec<super::Node<'a>> {} }