1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use xml::EventWriter;
use xml::writer::{EmitterConfig, XmlEvent};

pub use xml::writer::Error as XmlError;

pub struct XmlWriter<'a> {
    w: EventWriter<&'a mut Vec<u8>>,
}

impl<'a> XmlWriter<'a> {
    pub fn new(body: &'a mut Vec<u8>) -> XmlWriter<'a> {
        let writer = EmitterConfig::new()
            .perform_indent(true)
            .write_document_declaration(false)
            .create_writer(body);
        XmlWriter{w: writer}
    }

    pub fn write(&mut self, text: &str) -> Result<(), XmlError> {
        self.w.write(text)
    }

    pub fn start_element(&mut self, element: &str) -> Result<(), XmlError> {
        self.w.write(XmlEvent::start_element(element))
    }

    pub fn end_element(&mut self) -> Result<(), XmlError> {
        self.w.write(XmlEvent::end_element())
    }

    pub fn element<T: XmlSerializable>(&mut self, label: &str, content: &T) -> Result<(), XmlError> {
        self.start_element(label)?;
        content.write(self)?;
        self.end_element()
    }

    pub fn element_opt<T: XmlSerializable>(&mut self, label: &str, content: &Option<T>) -> Result<(), XmlError> {
        if let Some(ref content) = *content {
            self.start_element(label)?;
            content.write(self)?;
            self.end_element()
        } else {
            Ok(())
        }
    }

    pub fn array<T: XmlSerializable>(&mut self, array: &str, element: &str, items: &Vec<T>) -> Result<(), XmlError> {
        self.start_element(array)?;
        for item in items {
            self.element(element, item)?;
        }
        self.end_element()
    }
}

pub trait XmlSerializable {
    fn write(&self, &mut XmlWriter) -> Result<(), XmlError>;

    fn to_xml(&self) -> Result<String, XmlError> {
        let mut body = Vec::new();
        {
            let mut writer = XmlWriter::new(&mut body);
            self.write(&mut writer)?;
        }
        Ok(String::from_utf8(body).unwrap()) // FIXME: Don't unwrap? or document panic
    }
}

impl XmlSerializable for bool {
    fn write(&self, xml: &mut XmlWriter) -> Result<(), XmlError> {
        xml.write(match *self {true => "true", false => "false"})
    }
}
impl XmlSerializable for i32 {
    fn write(&self, xml: &mut XmlWriter) -> Result<(), XmlError> {
        xml.write(&self.to_string())
    }
}
impl XmlSerializable for i64 {
    fn write(&self, xml: &mut XmlWriter) -> Result<(), XmlError> {
        xml.write(&self.to_string())
    }
}
impl XmlSerializable for u32 {
    fn write(&self, xml: &mut XmlWriter) -> Result<(), XmlError> {
        xml.write(&self.to_string())
    }
}
impl XmlSerializable for u64 {
    fn write(&self, xml: &mut XmlWriter) -> Result<(), XmlError> {
        xml.write(&self.to_string())
    }
}
impl XmlSerializable for f32 {
    fn write(&self, xml: &mut XmlWriter) -> Result<(), XmlError> {
        xml.write(&self.to_string())
    }
}
impl XmlSerializable for f64 {
    fn write(&self, xml: &mut XmlWriter) -> Result<(), XmlError> {
        xml.write(&self.to_string())
    }
}
impl<'a> XmlSerializable for &'a str {
    fn write(&self, xml: &mut XmlWriter) -> Result<(), XmlError> {
        xml.write(self)
    }
}
impl XmlSerializable for String {
    fn write(&self, xml: &mut XmlWriter) -> Result<(), XmlError> {
        xml.write(&self)
    }
}