// This file is part of rss. // // Copyright © 2015-2021 The rust-syndication Developers // // This program is free software; you can redistribute it and/or modify // it under the terms of the MIT License and/or Apache 2.0 License. use std::collections::BTreeMap; use std::io::Write; use quick_xml::events::{BytesCData, BytesEnd, BytesStart, BytesText, Event}; use quick_xml::Error as XmlError; use quick_xml::Writer; pub trait ToXml { fn to_xml(&self, writer: &mut Writer) -> Result<(), XmlError>; fn used_namespaces(&self) -> BTreeMap { BTreeMap::new() } } impl<'a, T: ToXml> ToXml for &'a T { fn to_xml(&self, writer: &mut Writer) -> Result<(), XmlError> { (*self).to_xml(writer) } } pub trait WriterExt { fn write_text_element(&mut self, name: N, text: T) -> Result<(), XmlError> where N: AsRef, T: AsRef; fn write_text_elements(&mut self, name: N, values: I) -> Result<(), XmlError> where N: AsRef, T: AsRef, I: IntoIterator; fn write_cdata_element(&mut self, name: N, text: T) -> Result<(), XmlError> where N: AsRef, T: AsRef; fn write_object(&mut self, object: T) -> Result<(), XmlError> where T: ToXml; fn write_objects(&mut self, objects: I) -> Result<(), XmlError> where T: ToXml, I: IntoIterator; } impl WriterExt for Writer { fn write_text_element(&mut self, name: N, text: T) -> Result<(), XmlError> where N: AsRef, T: AsRef, { let name = name.as_ref(); self.write_event(Event::Start(BytesStart::new(name)))?; self.write_event(Event::Text(BytesText::new(text.as_ref())))?; self.write_event(Event::End(BytesEnd::new(name)))?; Ok(()) } fn write_text_elements(&mut self, name: N, values: I) -> Result<(), XmlError> where N: AsRef, T: AsRef, I: IntoIterator, { for value in values { self.write_text_element(&name, value)?; } Ok(()) } fn write_cdata_element(&mut self, name: N, text: T) -> Result<(), XmlError> where N: AsRef, T: AsRef, { let name = name.as_ref(); self.write_event(Event::Start(BytesStart::new(name)))?; BytesCData::escaped(text.as_ref()) .try_for_each(|event| self.write_event(Event::CData(event)))?; self.write_event(Event::End(BytesEnd::new(name)))?; Ok(()) } #[inline] fn write_object(&mut self, object: T) -> Result<(), XmlError> where T: ToXml, { object.to_xml(self) } fn write_objects(&mut self, objects: I) -> Result<(), XmlError> where T: ToXml, I: IntoIterator, { for object in objects { object.to_xml(self)?; } Ok(()) } }