use crate::Sodg;
use anyhow::Result;
use itertools::Itertools;
use xml_builder::{XMLBuilder, XMLElement, XMLVersion};
impl Sodg {
pub fn to_xml(&self) -> Result<String> {
let mut xml = XMLBuilder::new()
.version(XMLVersion::XML1_1)
.encoding("UTF-8".into())
.build();
let mut root = XMLElement::new("sodg");
for (v, vtx) in self
.vertices
.iter()
.sorted_by_key(|(v, _)| <&u32>::clone(v))
{
let mut v_node = XMLElement::new("v");
v_node.add_attribute("id", v.to_string().as_str());
for e in vtx.edges.iter().sorted_by_key(|e| e.a.clone()) {
let mut e_node = XMLElement::new("e");
e_node.add_attribute("a", e.a.as_str());
e_node.add_attribute("to", e.to.to_string().as_str());
v_node.add_child(e_node).unwrap();
}
if !vtx.data.is_empty() {
let mut data_node = XMLElement::new("data");
data_node
.add_text(vtx.data.print().replace('-', " "))
.unwrap();
v_node.add_child(data_node).unwrap();
}
root.add_child(v_node).unwrap();
}
xml.set_root_element(root);
let mut writer: Vec<u8> = Vec::new();
xml.generate(&mut writer).unwrap();
Ok(std::str::from_utf8(&writer)?.to_string())
}
}
#[cfg(test)]
use sxd_xpath::evaluate_xpath;
#[cfg(test)]
use crate::Hex;
#[test]
fn prints_simple_graph() -> Result<()> {
let mut g = Sodg::empty();
g.add(0)?;
g.put(0, Hex::from_str_bytes("hello"))?;
g.add(1)?;
g.bind(0, 1, "foo")?;
let xml = g.to_xml()?;
let parser = sxd_document::parser::parse(xml.as_str())?;
let doc = parser.as_document();
assert_eq!(
"foo",
evaluate_xpath(&doc, "/sodg/v[@id=0]/e[1]/@a")?.string()
);
assert_eq!(
"68 65 6C 6C 6F",
evaluate_xpath(&doc, "/sodg/v[@id=0]/data")?.string()
);
Ok(())
}