1 use html5ever::serialize::TraversalScope::*; 2 use html5ever::serialize::{serialize, Serialize, SerializeOpts, Serializer, TraversalScope}; 3 use html5ever::QualName; 4 use std::fs::File; 5 use std::io::{Result, Write}; 6 use std::path::Path; 7 use std::string::ToString; 8 9 use crate::tree::{NodeData, NodeRef}; 10 11 impl Serialize for NodeRef { serialize<S: Serializer>( &self, serializer: &mut S, traversal_scope: TraversalScope, ) -> Result<()>12 fn serialize<S: Serializer>( 13 &self, 14 serializer: &mut S, 15 traversal_scope: TraversalScope, 16 ) -> Result<()> { 17 match (traversal_scope, self.data()) { 18 (ref scope, &NodeData::Element(ref element)) => { 19 if *scope == IncludeNode { 20 let attrs = element.attributes.borrow(); 21 22 // Unfortunately we need to allocate something to hold these &'a QualName 23 let attrs = attrs 24 .map 25 .iter() 26 .map(|(name, attr)| { 27 ( 28 QualName::new( 29 attr.prefix.clone(), 30 name.ns.clone(), 31 name.local.clone(), 32 ), 33 &attr.value, 34 ) 35 }) 36 .collect::<Vec<_>>(); 37 38 serializer.start_elem( 39 element.name.clone(), 40 attrs.iter().map(|&(ref name, value)| (name, &**value)), 41 )? 42 } 43 44 for child in self.children() { 45 Serialize::serialize(&child, serializer, IncludeNode)? 46 } 47 48 if *scope == IncludeNode { 49 serializer.end_elem(element.name.clone())? 50 } 51 Ok(()) 52 } 53 54 (_, &NodeData::DocumentFragment) | (_, &NodeData::Document(_)) => { 55 for child in self.children() { 56 Serialize::serialize(&child, serializer, IncludeNode)? 57 } 58 Ok(()) 59 } 60 61 (ChildrenOnly(_), _) => Ok(()), 62 63 (IncludeNode, &NodeData::Doctype(ref doctype)) => { 64 serializer.write_doctype(&doctype.name) 65 } 66 (IncludeNode, &NodeData::Text(ref text)) => serializer.write_text(&text.borrow()), 67 (IncludeNode, &NodeData::Comment(ref text)) => serializer.write_comment(&text.borrow()), 68 (IncludeNode, &NodeData::ProcessingInstruction(ref contents)) => { 69 let contents = contents.borrow(); 70 serializer.write_processing_instruction(&contents.0, &contents.1) 71 } 72 } 73 } 74 } 75 76 impl ToString for NodeRef { 77 #[inline] to_string(&self) -> String78 fn to_string(&self) -> String { 79 let mut u8_vec = Vec::new(); 80 self.serialize(&mut u8_vec).unwrap(); 81 String::from_utf8(u8_vec).unwrap() 82 } 83 } 84 85 impl NodeRef { 86 /// Serialize this node and its descendants in HTML syntax to the given stream. 87 #[inline] serialize<W: Write>(&self, writer: &mut W) -> Result<()>88 pub fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> { 89 serialize( 90 writer, 91 self, 92 SerializeOpts { 93 traversal_scope: IncludeNode, 94 ..Default::default() 95 }, 96 ) 97 } 98 99 /// Serialize this node and its descendants in HTML syntax to a new file at the given path. 100 #[inline] serialize_to_file<P: AsRef<Path>>(&self, path: P) -> Result<()>101 pub fn serialize_to_file<P: AsRef<Path>>(&self, path: P) -> Result<()> { 102 let mut file = File::create(&path)?; 103 self.serialize(&mut file) 104 } 105 } 106