use std::borrow::Cow;
#[derive(Debug, Clone, PartialEq)]
pub enum DomEvent<'a> {
NodeStart {
tag: Cow<'a, str>,
namespace: Option<Cow<'a, str>>,
},
Attribute {
name: Cow<'a, str>,
value: Cow<'a, str>,
namespace: Option<Cow<'a, str>>,
},
ChildrenStart,
ChildrenEnd,
NodeEnd,
Text(Cow<'a, str>),
Comment(Cow<'a, str>),
ProcessingInstruction {
target: Cow<'a, str>,
data: Cow<'a, str>,
},
Doctype(Cow<'a, str>),
}
impl<'a> DomEvent<'a> {
pub fn is_node_start(&self) -> bool {
matches!(self, DomEvent::NodeStart { .. })
}
pub fn is_node_end(&self) -> bool {
matches!(self, DomEvent::NodeEnd)
}
pub fn is_attribute(&self) -> bool {
matches!(self, DomEvent::Attribute { .. })
}
pub fn is_text(&self) -> bool {
matches!(self, DomEvent::Text(_))
}
pub fn is_children_start(&self) -> bool {
matches!(self, DomEvent::ChildrenStart)
}
pub fn is_children_end(&self) -> bool {
matches!(self, DomEvent::ChildrenEnd)
}
pub fn trace(&self) -> TraceFmt<'_, 'a> {
TraceFmt(self)
}
}
pub struct TraceFmt<'r, 'a>(pub &'r DomEvent<'a>);
impl std::fmt::Display for TraceFmt<'_, '_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use owo_colors::OwoColorize;
match self.0 {
DomEvent::NodeStart { tag, namespace } => {
if let Some(ns) = namespace {
write!(f, "NodeStart {}<{}:{}>", "<".cyan(), ns, tag.cyan())
} else {
write!(f, "NodeStart {}{}{}", "<".cyan(), tag.cyan(), ">".cyan())
}
}
DomEvent::NodeEnd => write!(f, "NodeEnd {}", "</>".cyan()),
DomEvent::Attribute {
name,
value,
namespace,
} => {
if let Some(ns) = namespace {
write!(
f,
"Attribute {}{}:{}={}{}{}",
"@".yellow(),
ns,
name.yellow(),
"\"".yellow(),
value,
"\"".yellow()
)
} else {
write!(
f,
"Attribute {}{}={}{}{}",
"@".yellow(),
name.yellow(),
"\"".yellow(),
value,
"\"".yellow()
)
}
}
DomEvent::ChildrenStart => write!(f, "{}", "ChildrenStart".dimmed()),
DomEvent::ChildrenEnd => write!(f, "{}", "ChildrenEnd".dimmed()),
DomEvent::Text(t) => {
let preview: String = t.chars().take(40).collect();
if t.len() > 40 {
write!(
f,
"Text {}{}{}",
"\"".green(),
preview.green(),
"...\"".green()
)
} else {
write!(
f,
"Text {}{}{}",
"\"".green(),
preview.green(),
"\"".green()
)
}
}
DomEvent::Comment(c) => {
let preview: String = c.chars().take(20).collect();
write!(
f,
"Comment {}{}{}",
"<!--".dimmed(),
preview.dimmed(),
"-->".dimmed()
)
}
DomEvent::ProcessingInstruction { target, data } => {
write!(f, "ProcessingInstruction <?{target} {data}?>")
}
DomEvent::Doctype(d) => write!(f, "Doctype <!DOCTYPE {d}>"),
}
}
}