mod tests;
use std::io::Cursor;
use crate::xmlwriter::{xml_data_element_only, xml_declaration, xml_end_tag, xml_start_tag};
use crate::{CustomProperty, CustomPropertyType, DocProperties};
pub struct Custom {
pub(crate) writer: Cursor<Vec<u8>>,
pub(crate) properties: DocProperties,
}
impl Custom {
pub(crate) fn new() -> Custom {
let writer = Cursor::new(Vec::with_capacity(2048));
Custom {
writer,
properties: DocProperties::new(),
}
}
pub(crate) fn assemble_xml_file(&mut self) {
xml_declaration(&mut self.writer);
self.write_properties();
for (pid, property) in self.properties.custom_properties.clone().iter().enumerate() {
self.write_property(property, pid + 2);
}
xml_end_tag(&mut self.writer, "Properties");
}
fn write_properties(&mut self) {
let schema = "http://schemas.openxmlformats.org/officeDocument/2006".to_string();
let xmlns = format!("{schema}/custom-properties");
let xmlns_vt = format!("{schema}/docPropsVTypes");
let attributes = [("xmlns", xmlns), ("xmlns:vt", xmlns_vt)];
xml_start_tag(&mut self.writer, "Properties", &attributes);
}
fn write_property(&mut self, property: &CustomProperty, pid: usize) {
let fmtid = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}".to_string();
let attributes = [
("fmtid", fmtid),
("pid", pid.to_string()),
("name", property.name.clone()),
];
xml_start_tag(&mut self.writer, "property", &attributes);
match property.property_type {
CustomPropertyType::Int => self.write_vt_i_4(property.number_int),
CustomPropertyType::Bool => self.write_vt_bool(property.boolean),
CustomPropertyType::Real => self.write_vt_r_8(property.number_real),
CustomPropertyType::Text => self.write_vt_lpwstr(&property.text),
CustomPropertyType::DateTime => self.write_vt_filetime(&property.datetime),
}
xml_end_tag(&mut self.writer, "property");
}
fn write_vt_lpwstr(&mut self, text: &str) {
xml_data_element_only(&mut self.writer, "vt:lpwstr", text);
}
fn write_vt_filetime(&mut self, utc_datetime: &str) {
xml_data_element_only(&mut self.writer, "vt:filetime", utc_datetime);
}
fn write_vt_i_4(&mut self, number: i32) {
xml_data_element_only(&mut self.writer, "vt:i4", &number.to_string());
}
fn write_vt_r_8(&mut self, number: f64) {
xml_data_element_only(&mut self.writer, "vt:r8", &number.to_string());
}
fn write_vt_bool(&mut self, boolean: bool) {
xml_data_element_only(&mut self.writer, "vt:bool", &boolean.to_string());
}
}