Skip to main content

ppt_rs/generator/
package_cache.rs

1//! Cached static package parts reused across every generated deck.
2
3use std::sync::OnceLock;
4
5use super::layout_parts::{self, STANDARD_LAYOUT_COUNT};
6use super::slide_content::print_settings::PrintSettings;
7use super::theme_xml::create_slide_master_xml;
8
9const LAYOUT_RELS_XML: &str = r#"<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
10<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
11<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="../slideMasters/slideMaster1.xml"/>
12</Relationships>"#;
13
14static MASTER_RELS: OnceLock<String> = OnceLock::new();
15static DEFAULT_MASTER: OnceLock<String> = OnceLock::new();
16static DEFAULT_LAYOUTS: OnceLock<Vec<String>> = OnceLock::new();
17
18/// Whether print settings change layout/master placeholder XML.
19pub fn print_affects_theme_parts(print: Option<&PrintSettings>) -> bool {
20    print.is_some_and(|p| {
21        p.header.is_some()
22            || p.footer.is_some()
23            || p.print_date
24            || p.print_page_numbers
25    })
26}
27
28/// Cached `ppt/slideLayouts/_rels/slideLayoutN.xml.rels` (identical for every layout).
29pub fn layout_rels_xml() -> &'static str {
30    LAYOUT_RELS_XML
31}
32
33/// Cached `ppt/slideMasters/_rels/slideMaster1.xml.rels` for the standard layout count.
34pub fn master_rels_xml() -> &'static str {
35    MASTER_RELS
36        .get_or_init(|| layout_parts::create_master_rels_xml(STANDARD_LAYOUT_COUNT))
37        .as_str()
38}
39
40/// Cached slide master without footer/header placeholders.
41pub fn default_slide_master_xml() -> &'static str {
42    DEFAULT_MASTER
43        .get_or_init(|| create_slide_master_xml(None))
44        .as_str()
45}
46
47/// Cached `slideLayoutN.xml` without footer/header flags.
48pub fn default_layout_xml(layout_number: usize) -> &'static str {
49    default_layouts()[layout_number - 1].as_str()
50}
51
52fn default_layouts() -> &'static Vec<String> {
53    DEFAULT_LAYOUTS.get_or_init(|| {
54        (1..=STANDARD_LAYOUT_COUNT)
55            .map(|n| layout_parts::create_slide_layout_xml(n, None))
56            .collect()
57    })
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn cached_layouts_are_populated_once() {
66        assert_eq!(default_layouts().len(), STANDARD_LAYOUT_COUNT);
67        assert!(default_layout_xml(1).contains("Title Slide"));
68        assert!(default_slide_master_xml().contains("sldMaster"));
69        assert!(master_rels_xml().contains("slideLayout7.xml"));
70    }
71}