use crate::writer::{Result, XmlWriter};
use std::io::Write;
use xlsbye_core::types::SharedStringTable;
use xlsbye_core::xml_names::SPREADSHEET_NS;
pub fn write_shared_strings(
writer: impl Write,
sst: &SharedStringTable,
count: u32,
unique_count: u32,
) -> Result<()> {
let mut writer = XmlWriter::new(writer);
writer.write_xml_declaration()?;
writer.write_start_element_with_ns(
"sst",
[("", SPREADSHEET_NS)],
[
("count", count.to_string()),
("uniqueCount", unique_count.to_string()),
],
)?;
for entry in sst {
writer.write_start_element("si", std::iter::empty::<(&str, &str)>())?;
match entry {
xlsbye_core::types::SharedStringEntry::Plain(text) => {
write_text_node(&mut writer, "t", text)?;
}
xlsbye_core::types::SharedStringEntry::Rich(runs) => {
for run in runs {
writer.write_start_element("r", std::iter::empty::<(&str, &str)>())?;
if let Some(font_index) = run.font_index {
writer.write_start_element("rPr", std::iter::empty::<(&str, &str)>())?;
writer.write_empty_element("rFont", [("val", format!("font{}", font_index))])?;
writer.write_end_element("rPr")?;
}
write_text_node(&mut writer, "t", &run.text)?;
writer.write_end_element("r")?;
}
}
}
writer.write_end_element("si")?;
}
writer.write_end_element("sst")?;
Ok(())
}
pub(crate) fn write_text_node<W: Write>(
writer: &mut XmlWriter<W>,
tag_name: &str,
text: &str,
) -> Result<()> {
if needs_space_preserve(text) {
writer.write_text_element(tag_name, [("xml:space", "preserve")], text)
} else {
writer.write_text_element(tag_name, std::iter::empty::<(&str, &str)>(), text)
}
}
fn needs_space_preserve(text: &str) -> bool {
text.chars().next().is_some_and(char::is_whitespace)
|| text.chars().last().is_some_and(char::is_whitespace)
}