oxihuman_export/
graphml_export.rs1#![allow(dead_code)]
7
8#[allow(dead_code)]
10#[derive(Debug, Clone)]
11pub struct GraphMlNode {
12 pub id: String,
13 pub label: String,
14}
15
16#[allow(dead_code)]
18#[derive(Debug, Clone)]
19pub struct GraphMlEdge {
20 pub source: String,
21 pub target: String,
22 pub id: String,
23}
24
25#[allow(dead_code)]
27#[derive(Debug, Clone, Default)]
28pub struct GraphMlExport {
29 pub graph_id: String,
30 pub directed: bool,
31 pub nodes: Vec<GraphMlNode>,
32 pub edges: Vec<GraphMlEdge>,
33}
34
35#[allow(dead_code)]
37pub fn new_graphml_export(graph_id: &str, directed: bool) -> GraphMlExport {
38 GraphMlExport {
39 graph_id: graph_id.to_string(),
40 directed,
41 nodes: Vec::new(),
42 edges: Vec::new(),
43 }
44}
45
46#[allow(dead_code)]
48pub fn add_graphml_node(doc: &mut GraphMlExport, id: &str, label: &str) {
49 doc.nodes.push(GraphMlNode {
50 id: id.to_string(),
51 label: label.to_string(),
52 });
53}
54
55#[allow(dead_code)]
57pub fn add_graphml_edge(doc: &mut GraphMlExport, source: &str, target: &str) {
58 let edge_id = format!("e{}", doc.edges.len());
59 doc.edges.push(GraphMlEdge {
60 source: source.to_string(),
61 target: target.to_string(),
62 id: edge_id,
63 });
64}
65
66#[allow(dead_code)]
68pub fn graphml_node_count(doc: &GraphMlExport) -> usize {
69 doc.nodes.len()
70}
71
72#[allow(dead_code)]
74pub fn graphml_edge_count(doc: &GraphMlExport) -> usize {
75 doc.edges.len()
76}
77
78#[allow(dead_code)]
80pub fn to_graphml_string(doc: &GraphMlExport) -> String {
81 let edge_default = if doc.directed {
82 "directed"
83 } else {
84 "undirected"
85 };
86 let mut out = String::from("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
87 out.push_str("<graphml xmlns=\"http://graphml.graphdrawing.org/graphml\">\n");
88 out.push_str(&format!(
89 " <graph id=\"{}\" edgedefault=\"{}\">\n",
90 doc.graph_id, edge_default
91 ));
92 for node in &doc.nodes {
93 out.push_str(&format!(
94 " <node id=\"{}\"><data key=\"label\">{}</data></node>\n",
95 node.id, node.label
96 ));
97 }
98 for edge in &doc.edges {
99 out.push_str(&format!(
100 " <edge id=\"{}\" source=\"{}\" target=\"{}\"/>\n",
101 edge.id, edge.source, edge.target
102 ));
103 }
104 out.push_str(" </graph>\n</graphml>");
105 out
106}
107
108#[allow(dead_code)]
110pub fn find_graphml_node<'a>(doc: &'a GraphMlExport, id: &str) -> Option<&'a GraphMlNode> {
111 doc.nodes.iter().find(|n| n.id == id)
112}
113
114#[allow(dead_code)]
116pub fn export_bones_graphml(bones: &[(&str, Option<&str>)]) -> String {
117 let mut doc = new_graphml_export("skeleton", true);
118 for &(bone, parent) in bones {
119 add_graphml_node(&mut doc, bone, bone);
120 if let Some(p) = parent {
121 add_graphml_edge(&mut doc, p, bone);
122 }
123 }
124 to_graphml_string(&doc)
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130
131 #[test]
132 fn test_new_graphml_empty() {
133 let doc = new_graphml_export("g", true);
134 assert_eq!(graphml_node_count(&doc), 0);
135 assert_eq!(graphml_edge_count(&doc), 0);
136 }
137
138 #[test]
139 fn test_add_node() {
140 let mut doc = new_graphml_export("g", true);
141 add_graphml_node(&mut doc, "n1", "Node 1");
142 assert_eq!(graphml_node_count(&doc), 1);
143 }
144
145 #[test]
146 fn test_add_edge() {
147 let mut doc = new_graphml_export("g", true);
148 add_graphml_edge(&mut doc, "a", "b");
149 assert_eq!(graphml_edge_count(&doc), 1);
150 }
151
152 #[test]
153 fn test_to_graphml_contains_xml_header() {
154 let doc = new_graphml_export("g", true);
155 let s = to_graphml_string(&doc);
156 assert!(s.contains("<?xml"));
157 }
158
159 #[test]
160 fn test_to_graphml_contains_graph_id() {
161 let doc = new_graphml_export("mygraph", true);
162 let s = to_graphml_string(&doc);
163 assert!(s.contains("mygraph"));
164 }
165
166 #[test]
167 fn test_to_graphml_contains_node() {
168 let mut doc = new_graphml_export("g", true);
169 add_graphml_node(&mut doc, "hip", "Hip");
170 let s = to_graphml_string(&doc);
171 assert!(s.contains("hip"));
172 }
173
174 #[test]
175 fn test_to_graphml_contains_edge() {
176 let mut doc = new_graphml_export("g", true);
177 add_graphml_edge(&mut doc, "a", "b");
178 let s = to_graphml_string(&doc);
179 assert!(s.contains("<edge"));
180 }
181
182 #[test]
183 fn test_find_graphml_node() {
184 let mut doc = new_graphml_export("g", true);
185 add_graphml_node(&mut doc, "knee", "Knee");
186 assert!(find_graphml_node(&doc, "knee").is_some());
187 }
188
189 #[test]
190 fn test_export_bones_graphml() {
191 let bones = vec![("root", None), ("spine", Some("root"))];
192 let s = export_bones_graphml(&bones);
193 assert!(s.contains("skeleton"));
194 }
195
196 #[test]
197 fn test_undirected_edge_default() {
198 let doc = new_graphml_export("g", false);
199 let s = to_graphml_string(&doc);
200 assert!(s.contains("undirected"));
201 }
202}