1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- use std::fmt::{Display};
- use std::io::{self, Write};
- use std::iter::repeat;
- /// An `XMLWriter` is a wrapper over a `Write` value that provides
- /// helper functions for generating (mostly) well-formed XML.
- pub struct XMLWriter<'a>{
- writer: &'a mut Write,
- indent: usize,
- }
- impl<'a> XMLWriter<'a> {
- /// Create a new XMLWriter and add an XML version/encoding header
- /// on top
- pub fn start(buf: &'a mut Write) -> io::Result<XMLWriter<'a>> {
- writeln!(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>")?;
- Ok(XMLWriter { writer: buf, indent: 0, })
- }
- fn indent(&mut self) -> io::Result<()> {
- write!(self.writer, "{}", repeat(' ').take(self.indent).collect::<String>())?;
- Ok(())
- }
- /// create an complete tag with the given attributes
- pub fn tag(&mut self, name: &str, attrs: &[(&str, &Display)]) -> io::Result<()> {
- self.indent()?;
- write!(self.writer, "<{}", name)?;
- for &(k, v) in attrs {
- write!(self.writer, " {}=\"{}\"", k, v)?;
- }
- writeln!(self.writer, "/>")?;
- Ok(())
- }
- /// create an open tag with the given attributes; you must close
- /// it manually later
- pub fn open(&mut self, name: &str, attrs: &[(&str, &Display)]) -> io::Result<()> {
- self.indent()?;
- write!(self.writer, "<{}", name)?;
- for &(k, v) in attrs {
- write!(self.writer, " {}=\"{}\"", k, v)?;
- }
- writeln!(self.writer, ">")?;
- Ok(())
- }
- /// close a tag with the given attributes
- pub fn close(&mut self, name: &str) -> io::Result<()> {
- self.indent()?;
- write!(self.writer, "</{}>", name)?;
- Ok(())
- }
- /// create an open-close tag pair with the given attributes,
- /// calling the provided function in order to fill in the interior
- /// tags as well
- pub fn block<F>(
- &mut self,
- name: &str,
- attrs: &[(&str, &Display)],
- cb: F
- ) -> io::Result<()>
- where F: FnOnce(&mut XMLWriter<'a>) -> io::Result<()>
- {
- self.indent()?;
- write!(self.writer, "<{}", name)?;
- for &(k, v) in attrs {
- write!(self.writer, " {}=\"{}\"", k, v)?;
- }
- writeln!(self.writer, ">")?;
- self.indent += 2;
- cb(self)?;
- self.indent -= 2;
- write!(self.writer, "</{}>", name)?;
- Ok(())
- }
- }
|