use crate::style::Style;
#[derive(Debug, Clone, PartialEq)]
pub enum Tag {
Html,
Head,
Meta,
Title,
Body,
Div,
Span,
Table,
Tbody,
Tr,
Td,
Th,
P,
H1,
H2,
H3,
H4,
H5,
H6,
A,
Img,
Hr,
Br,
Pre,
Code,
Strong,
Em,
Custom(String),
}
impl Tag {
pub fn as_str(&self) -> &str {
match self {
Tag::Html => "html",
Tag::Head => "head",
Tag::Meta => "meta",
Tag::Title => "title",
Tag::Body => "body",
Tag::Div => "div",
Tag::Span => "span",
Tag::Table => "table",
Tag::Tbody => "tbody",
Tag::Tr => "tr",
Tag::Td => "td",
Tag::Th => "th",
Tag::P => "p",
Tag::H1 => "h1",
Tag::H2 => "h2",
Tag::H3 => "h3",
Tag::H4 => "h4",
Tag::H5 => "h5",
Tag::H6 => "h6",
Tag::A => "a",
Tag::Img => "img",
Tag::Hr => "hr",
Tag::Br => "br",
Tag::Pre => "pre",
Tag::Code => "code",
Tag::Strong => "strong",
Tag::Em => "em",
Tag::Custom(name) => name.as_str(),
}
}
pub fn is_void(&self) -> bool {
matches!(self, Tag::Meta | Tag::Img | Tag::Hr | Tag::Br)
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Attr {
pub name: String,
pub value: String,
}
impl Attr {
pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
Attr {
name: name.into(),
value: value.into(),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Element {
pub tag: Tag,
pub attrs: Vec<Attr>,
pub style: Style,
pub children: Vec<Node>,
}
impl Element {
pub fn new(tag: Tag) -> Self {
Element {
tag,
attrs: Vec::new(),
style: Style::default(),
children: Vec::new(),
}
}
pub fn attr(mut self, name: impl Into<String>, value: impl Into<String>) -> Self {
self.attrs.push(Attr::new(name, value));
self
}
pub fn style(mut self, style: Style) -> Self {
self.style = style;
self
}
pub fn child(mut self, child: Node) -> Self {
self.children.push(child);
self
}
pub fn children(mut self, children: impl IntoIterator<Item = Node>) -> Self {
self.children.extend(children);
self
}
}
#[derive(Debug, Clone, PartialEq)]
#[allow(clippy::large_enum_variant)]
pub enum Node {
Element(Element),
Text(String),
Fragment(Vec<Node>),
None,
}
impl Node {
pub fn text(content: impl Into<String>) -> Self {
Node::Text(content.into())
}
pub fn element(tag: Tag) -> Element {
Element::new(tag)
}
pub fn fragment(nodes: Vec<Node>) -> Self {
Node::Fragment(nodes)
}
}