use std::io;
use std::io::Write;
use std::string::ToString;
use html5ever::serialize::{
serialize, Serialize, SerializeOpts, Serializer,
TraversalScope, TraversalScope::*
};
use crate::dom::{Document, NodeData, NodeRef};
impl<'a> Serialize for NodeRef<'a> {
fn serialize<S>(
&self,
serializer: &mut S,
traversal_scope: TraversalScope)
-> io::Result<()>
where S: Serializer
{
use NodeData::*;
match (traversal_scope, &self.data) {
(ref scope, Elem(ref elm)) => {
if *scope == IncludeNode {
serializer.start_elem(
elm.name.clone(),
elm.attrs.iter().map(|a| (&a.name, a.value.as_ref()))
)?;
}
for child in self.children() {
Serialize::serialize(&child, serializer, IncludeNode)?;
}
if *scope == IncludeNode {
serializer.end_elem(elm.name.clone())?;
}
Ok(())
}
(_, Hole) => {
panic!("Hole in Document")
}
(_, Document) => {
for child in self.children() {
Serialize::serialize(&child, serializer, IncludeNode)?;
}
Ok(())
}
(ChildrenOnly(_), _) => Ok(()),
(IncludeNode, DocType(ref dt)) => {
serializer.write_doctype(&dt.name)
}
(IncludeNode, Text(ref t)) => {
serializer.write_text(&t)
}
(IncludeNode, Comment(ref t)) => {
serializer.write_comment(&t)
}
(IncludeNode, Pi(ref pi)) => {
serializer.write_processing_instruction(&"", &pi.data)
}
}
}
}
impl ToString for Document {
fn to_string(&self) -> String {
let mut u8_vec = Vec::new();
self.serialize(&mut u8_vec).unwrap();
unsafe { String::from_utf8_unchecked(u8_vec) }
}
}
impl Document {
pub fn serialize<W>(&self, writer: &mut W) -> io::Result<()>
where W: Write
{
serialize(
writer,
&self.document_node_ref(),
SerializeOpts {
traversal_scope: ChildrenOnly(None),
..Default::default()
},
)
}
}
impl<'a> NodeRef<'a> {
pub fn serialize<W>(&'a self, writer: &mut W) -> io::Result<()>
where W: Write
{
serialize(
writer,
self,
SerializeOpts {
traversal_scope: IncludeNode,
..Default::default()
},
)
}
}
impl<'a> ToString for NodeRef<'a> {
fn to_string(&self) -> String {
let mut u8_vec = Vec::new();
self.serialize(&mut u8_vec).unwrap();
unsafe { String::from_utf8_unchecked(u8_vec) }
}
}