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
use super::*;
#[derive(Serialize)]
pub struct DataContractWriter {
namespace: String,
class_name: String,
table_name: String,
items: Vec<XmlItem>,
}
#[derive(Serialize)]
pub struct XmlItem {
is_vector: bool,
fields: Vec<XmlField>,
}
#[derive(Serialize)]
pub struct XmlField {
name: String,
data: String,
}
impl DataContractWriter {
pub fn new(namespace: &str, table: &XTable, table_suffix: &str) -> Self {
Self {
class_name: table.name.clone(),
table_name: format!("{}{}", table.name, table_suffix),
namespace: namespace.to_string(),
items: table.as_xml(),
}
}
pub fn write_xml(&self, output: &Path) -> XResult<()> {
let ctx = Context::from_serialize(self)?;
tera_render(include_str!("DataContract.xml.djv"), &ctx, output, "DataContract.xml")?;
Ok(())
}
}
impl XTable {
fn as_xml(&self) -> Vec<XmlItem> {
let headers = self.data.headers();
self.data.rows().iter().map(|v| XmlItem { is_vector: false, fields: v.as_xml(&headers) }).collect()
}
}
impl XDataItem {
fn as_xml(&self, headers: &[&XCellHeader]) -> Vec<XmlField> {
let mut out = vec![];
for (i, datum) in self.data.iter().enumerate() {
let field = match headers.get(i) {
Some(s) => s.field_name.to_string(),
None => break,
};
let data = match datum {
XCellValue::Boolean(v) => v.to_string(),
_ => datum.to_string(),
};
out.push(XmlField { name: field, data })
}
out.into_iter().sorted_by_key(|v| v.name.to_owned()).collect()
}
}