mod tests;
use std::io::Cursor;
use crate::xmlwriter::{
xml_data_element_only, xml_declaration, xml_end_tag, xml_start_tag, xml_start_tag_only,
};
use crate::DocProperties;
pub struct App {
pub(crate) writer: Cursor<Vec<u8>>,
heading_pairs: Vec<(String, u16)>,
table_parts: Vec<String>,
pub(crate) doc_security: u8,
pub(crate) properties: DocProperties,
}
impl App {
pub(crate) fn new() -> App {
let writer = Cursor::new(Vec::with_capacity(2048));
App {
writer,
heading_pairs: vec![],
table_parts: vec![],
doc_security: 0,
properties: DocProperties::new(),
}
}
pub(crate) fn add_heading_pair(&mut self, key: &str, value: u16) {
if value > 0 {
self.heading_pairs.push((key.to_string(), value));
}
}
pub(crate) fn add_part_name(&mut self, part_name: &str) {
self.table_parts.push(part_name.to_string());
}
pub(crate) fn assemble_xml_file(&mut self) {
xml_declaration(&mut self.writer);
self.write_properties();
self.write_application();
self.write_doc_security();
self.write_scale_crop();
self.write_heading_pairs();
self.write_titles_of_parts();
self.write_manager();
self.write_company();
self.write_links_up_to_date();
self.write_shared_doc();
self.write_hyperlink_base();
self.write_hyperlinks_changed();
self.write_app_version();
xml_end_tag(&mut self.writer, "Properties");
}
fn write_properties(&mut self) {
let xmlns =
"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties".to_string();
let xmlns_vt =
"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes".to_string();
let attributes = vec![("xmlns", xmlns), ("xmlns:vt", xmlns_vt)];
xml_start_tag(&mut self.writer, "Properties", &attributes);
}
fn write_application(&mut self) {
xml_data_element_only(&mut self.writer, "Application", "Microsoft Excel");
}
fn write_doc_security(&mut self) {
xml_data_element_only(
&mut self.writer,
"DocSecurity",
&self.doc_security.to_string(),
);
}
fn write_scale_crop(&mut self) {
xml_data_element_only(&mut self.writer, "ScaleCrop", "false");
}
fn write_heading_pairs(&mut self) {
xml_start_tag_only(&mut self.writer, "HeadingPairs");
self.write_heading_vector();
xml_end_tag(&mut self.writer, "HeadingPairs");
}
fn write_heading_vector(&mut self) {
let size = self.heading_pairs.len() * 2;
let size = size.to_string();
let attributes = vec![("size", size), ("baseType", "variant".to_string())];
xml_start_tag(&mut self.writer, "vt:vector", &attributes);
for heading_pair in self.heading_pairs.clone() {
xml_start_tag_only(&mut self.writer, "vt:variant");
self.write_vt_lpstr(&heading_pair.0);
xml_end_tag(&mut self.writer, "vt:variant");
xml_start_tag_only(&mut self.writer, "vt:variant");
self.write_vt_i4(heading_pair.1);
xml_end_tag(&mut self.writer, "vt:variant");
}
xml_end_tag(&mut self.writer, "vt:vector");
}
fn write_titles_of_parts(&mut self) {
xml_start_tag_only(&mut self.writer, "TitlesOfParts");
self.write_title_parts_vector();
xml_end_tag(&mut self.writer, "TitlesOfParts");
}
fn write_title_parts_vector(&mut self) {
let size = self.table_parts.len();
let size = size.to_string();
let attributes = vec![("size", size), ("baseType", String::from("lpstr"))];
xml_start_tag(&mut self.writer, "vt:vector", &attributes);
for part_name in self.table_parts.clone() {
self.write_vt_lpstr(&part_name);
}
xml_end_tag(&mut self.writer, "vt:vector");
}
fn write_vt_lpstr(&mut self, data: &str) {
xml_data_element_only(&mut self.writer, "vt:lpstr", data);
}
fn write_vt_i4(&mut self, count: u16) {
xml_data_element_only(&mut self.writer, "vt:i4", &count.to_string());
}
fn write_manager(&mut self) {
if !self.properties.manager.is_empty() {
xml_data_element_only(&mut self.writer, "Manager", &self.properties.manager);
}
}
fn write_company(&mut self) {
xml_data_element_only(&mut self.writer, "Company", &self.properties.company);
}
fn write_links_up_to_date(&mut self) {
xml_data_element_only(&mut self.writer, "LinksUpToDate", "false");
}
fn write_shared_doc(&mut self) {
xml_data_element_only(&mut self.writer, "SharedDoc", "false");
}
fn write_hyperlink_base(&mut self) {
if !self.properties.hyperlink_base.is_empty() {
xml_data_element_only(
&mut self.writer,
"HyperlinkBase",
&self.properties.hyperlink_base,
);
}
}
fn write_hyperlinks_changed(&mut self) {
xml_data_element_only(&mut self.writer, "HyperlinksChanged", "false");
}
fn write_app_version(&mut self) {
xml_data_element_only(&mut self.writer, "AppVersion", "12.0000");
}
}