mod tests;
use std::io::Cursor;
use std::sync::{Arc, Mutex};
use crate::shared_strings_table::SharedStringsTable;
use crate::xmlwriter::{
xml_declaration, xml_end_tag, xml_rich_si_element, xml_si_element, xml_start_tag,
};
pub struct SharedStrings {
pub(crate) writer: Cursor<Vec<u8>>,
}
impl SharedStrings {
pub(crate) fn new() -> SharedStrings {
let writer = Cursor::new(Vec::with_capacity(2048));
SharedStrings { writer }
}
pub(crate) fn assemble_xml_file(&mut self, string_table: Arc<Mutex<SharedStringsTable>>) {
xml_declaration(&mut self.writer);
self.write_sst(&string_table);
self.write_sst_strings(&string_table);
xml_end_tag(&mut self.writer, "sst");
}
fn write_sst(&mut self, string_table: &Arc<Mutex<SharedStringsTable>>) {
let string_table = string_table.lock().unwrap();
let xmls = "http://schemas.openxmlformats.org/spreadsheetml/2006/main".to_string();
let count = string_table.count.to_string();
let unique = string_table.unique_count.to_string();
let attributes = [("xmlns", xmls), ("count", count), ("uniqueCount", unique)];
xml_start_tag(&mut self.writer, "sst", &attributes);
}
#[allow(clippy::from_iter_instead_of_collect)] fn write_sst_strings(&mut self, string_table: &Arc<Mutex<SharedStringsTable>>) {
let string_table = string_table.lock().unwrap();
let mut insertion_order_strings = Vec::from_iter(string_table.strings.iter());
insertion_order_strings.sort_by_key(|x| x.1);
let whitespace = ['\t', '\n', ' '];
for (string, _) in insertion_order_strings {
let preserve_whitespace =
string.starts_with(whitespace) || string.ends_with(whitespace);
if string.starts_with("<r>") && string.ends_with("</r>") {
xml_rich_si_element(&mut self.writer, string);
} else {
xml_si_element(&mut self.writer, string, preserve_whitespace);
}
}
}
}