use std::fmt;
use crate::xml::attribute::OwnedAttribute;
use crate::xml::common::XmlVersion;
use crate::xml::name::OwnedName;
use crate::xml::namespace::Namespace;
#[derive(PartialEq, Eq, Clone)]
pub enum XmlEvent {
StartDocument {
version: XmlVersion,
encoding: String,
standalone: Option<bool>,
},
EndDocument,
ProcessingInstruction {
name: String,
data: Option<String>,
},
StartElement {
name: OwnedName,
attributes: Vec<OwnedAttribute>,
namespace: Namespace,
},
EndElement {
name: OwnedName,
},
Characters(String),
}
impl fmt::Debug for XmlEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
XmlEvent::StartDocument {
ref version,
ref encoding,
ref standalone,
} => write!(
f,
"StartDocument({}, {}, {:?})",
version, *encoding, *standalone
),
XmlEvent::EndDocument => write!(f, "EndDocument"),
XmlEvent::ProcessingInstruction { ref name, ref data } => write!(
f,
"ProcessingInstruction({}{})",
*name,
match *data {
Some(ref data) => format!(", {}", data),
None => String::new(),
}
),
XmlEvent::StartElement {
ref name,
ref attributes,
namespace: Namespace(ref namespace),
} => write!(
f,
"StartElement({}, {:?}{})",
name,
namespace,
if attributes.is_empty() {
String::new()
} else {
let attributes: Vec<String> = attributes
.iter()
.map(|a| format!("{} -> {}", a.name, a.value))
.collect();
format!(", [{}]", attributes.join(", "))
}
),
XmlEvent::EndElement { ref name } => write!(f, "EndElement({})", name),
XmlEvent::Characters(ref data) => write!(f, "Characters({})", data),
}
}
}
impl XmlEvent {
#[cfg(test)]
pub fn as_writer_event(&self) -> Option<crate::xml::writer::events::XmlEvent<'_>> {
match *self {
XmlEvent::StartDocument {
version,
ref encoding,
standalone,
} => Some(crate::xml::writer::events::XmlEvent::StartDocument {
version,
encoding: Some(encoding),
standalone,
}),
XmlEvent::ProcessingInstruction { ref name, ref data } => Some(
crate::xml::writer::events::XmlEvent::ProcessingInstruction {
name,
data: data.as_ref().map(|s| &s[..]),
},
),
XmlEvent::StartElement {
ref name,
ref attributes,
ref namespace,
} => Some(crate::xml::writer::events::XmlEvent::StartElement {
name: name.borrow(),
attributes: attributes.iter().map(|a| a.borrow()).collect(),
namespace: std::borrow::Cow::Borrowed(namespace),
}),
XmlEvent::EndElement { ref name } => {
Some(crate::xml::writer::events::XmlEvent::EndElement {
name: Some(name.borrow()),
})
}
XmlEvent::Characters(ref data) => {
Some(crate::xml::writer::events::XmlEvent::Characters(data))
}
_ => None,
}
}
}
#[test]
fn test_xml_event() {
use std::str;
use crate::xml::reader::XmlEvent as ReaderEvent;
use crate::xml::writer::XmlEvent as WriterEvent;
use crate::xml::{EventReader, EventWriter};
let mut input: &[u8] = b"<hello>world</hello>";
let mut output: Vec<u8> = Vec::new();
{
let reader = EventReader::new(&mut input);
let mut writer = EventWriter::new(&mut output);
for e in reader {
match e.unwrap() {
ReaderEvent::Characters(s) => writer
.write(WriterEvent::characters(&s.to_uppercase()))
.unwrap(),
e => {
if let Some(e) = e.as_writer_event() {
writer.write(e).unwrap()
}
}
}
}
}
assert_eq!(
str::from_utf8(&output).unwrap(),
r#"<?xml version="1.0" encoding="UTF-8"?><hello>WORLD</hello>"#
);
}