pptx_rs/opc/
content_types.rs1use std::collections::BTreeMap;
23
24#[derive(Debug, Clone)]
26pub struct DefaultExt {
27 pub extension: String,
29 pub content_type: String,
31}
32
33impl DefaultExt {
34 pub fn new(ext: impl Into<String>, ct: impl Into<String>) -> Self {
36 DefaultExt {
37 extension: ext.into().trim_start_matches('.').to_string(),
38 content_type: ct.into(),
39 }
40 }
41}
42
43#[derive(Debug, Clone)]
45pub struct Override {
46 pub partname: String,
48 pub content_type: String,
50}
51
52#[derive(Debug, Clone, Default)]
57pub struct ContentTypes {
58 pub defaults: Vec<DefaultExt>,
60 pub overrides: Vec<Override>,
62 by_partname: BTreeMap<String, usize>,
63}
64
65impl ContentTypes {
66 #[allow(clippy::field_reassign_with_default)]
70 pub fn new_default() -> Self {
71 let mut ct = ContentTypes::default();
72 ct.defaults.push(DefaultExt::new("xml", "application/xml"));
73 ct.defaults.push(DefaultExt::new(
74 "rels",
75 "application/vnd.openxmlformats-package.relationships+xml",
76 ));
77 ct.defaults.push(DefaultExt::new("png", "image/png"));
78 ct.defaults.push(DefaultExt::new("jpeg", "image/jpeg"));
79 ct.defaults.push(DefaultExt::new("jpg", "image/jpeg"));
80 ct.defaults.push(DefaultExt::new("gif", "image/gif"));
81 ct.defaults.push(DefaultExt::new("bmp", "image/bmp"));
82 ct.defaults.push(DefaultExt::new("svg", "image/svg+xml"));
83 ct
84 }
85
86 pub fn add_override(&mut self, partname: &str, content_type: &str) {
90 if self.by_partname.contains_key(partname) {
91 return;
92 }
93 let idx = self.overrides.len();
94 self.overrides.push(Override {
95 partname: partname.to_string(),
96 content_type: content_type.to_string(),
97 });
98 self.by_partname.insert(partname.to_string(), idx);
99 }
100
101 pub fn has_override(&self, partname: &str) -> bool {
103 self.by_partname.contains_key(partname)
104 }
105
106 pub fn to_xml(&self) -> String {
108 let mut s = String::with_capacity(512);
109 s.push_str("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
110 s.push_str(
111 "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">",
112 );
113 for d in &self.defaults {
114 s.push_str(&format!(
115 "<Default Extension=\"{}\" ContentType=\"{}\"/>",
116 super::rels::xml_escape(&d.extension),
117 super::rels::xml_escape(&d.content_type),
118 ));
119 }
120 for o in &self.overrides {
121 s.push_str(&format!(
122 "<Override PartName=\"{}\" ContentType=\"{}\"/>",
123 super::rels::xml_escape(&o.partname),
124 super::rels::xml_escape(&o.content_type),
125 ));
126 }
127 s.push_str("</Types>");
128 s
129 }
130}