Skip to main content

xlsbye_xml/
external_links.rs

1use std::io::Write;
2
3use xlsbye_core::types::ParsedExternalLink;
4use xlsbye_core::xml_names::{RELATIONSHIPS_NS, SPREADSHEET_NS};
5
6use crate::writer::{Result, XmlWriter};
7
8pub fn write_external_link(writer: impl Write, link: &ParsedExternalLink) -> Result<()> {
9    let mut writer = XmlWriter::new(writer);
10    writer.write_xml_declaration()?;
11    writer.write_start_element_with_ns(
12        "externalLink",
13        [("", SPREADSHEET_NS), ("r", RELATIONSHIPS_NS)],
14        std::iter::empty::<(&str, &str)>(),
15    )?;
16
17    let rel_id = link.rel_id.as_deref().unwrap_or("rId1");
18    writer.write_start_element("externalBook", [("r:id", rel_id)])?;
19
20    if !link.sheet_names.is_empty() {
21        writer.write_start_element("sheetNames", std::iter::empty::<(&str, &str)>())?;
22        for sheet_name in &link.sheet_names {
23            writer.write_empty_element("sheetName", [("val", sheet_name.as_str())])?;
24        }
25        writer.write_end_element("sheetNames")?;
26    }
27
28    writer.write_end_element("externalBook")?;
29    writer.write_end_element("externalLink")
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test]
37    fn writes_external_link_xml() {
38        let parsed = ParsedExternalLink {
39            rel_id: Some("rId9".to_string()),
40            sheet_names: vec!["Sheet1".to_string(), "Sheet Two".to_string()],
41        };
42
43        let mut out = Vec::new();
44        write_external_link(&mut out, &parsed).expect("external link xml should be written");
45        let xml = String::from_utf8(out).expect("utf-8 xml");
46
47        assert!(xml.contains("<externalLink "));
48        assert!(xml.contains("<externalBook r:id=\"rId9\">"));
49        assert!(xml.contains("<sheetName val=\"Sheet1\"/>"));
50        assert!(xml.contains("<sheetName val=\"Sheet Two\"/>"));
51    }
52}