msix/
content_types.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashSet;
3use std::path::Path;
4
5#[derive(Clone, Debug)]
6pub struct ContentTypesBuilder {
7    ext: HashSet<String>,
8    inner: Option<ContentTypes>,
9}
10
11impl ContentTypesBuilder {
12    pub fn add(&mut self, path: &Path) {
13        if let Some(ext) = path.extension() {
14            if let Some(ext) = ext.to_str() {
15                if !self.ext.contains(ext) {
16                    let mime = mime_guess::from_ext(ext).first_or_octet_stream();
17                    self.inner.as_mut().unwrap().rules.push(Rule::Default {
18                        ext: ext.into(),
19                        mime: mime.to_string(),
20                    });
21                    self.ext.insert(ext.to_string());
22                }
23            }
24        }
25    }
26
27    pub fn finish(&mut self) -> ContentTypes {
28        self.inner.take().unwrap()
29    }
30}
31
32impl Default for ContentTypesBuilder {
33    fn default() -> Self {
34        Self {
35            ext: Default::default(),
36            inner: Some(Default::default()),
37        }
38    }
39}
40
41#[derive(Clone, Debug, Deserialize, Serialize)]
42#[serde(rename(serialize = "Types"))]
43pub struct ContentTypes {
44    #[serde(default = "default_namespace")]
45    xmlns: String,
46    pub rules: Vec<Rule>,
47}
48
49impl Default for ContentTypes {
50    fn default() -> Self {
51        Self {
52            xmlns: default_namespace(),
53            rules: vec![
54                Rule::Override {
55                    part_name: "/AppxBlockMap.xml".into(),
56                    mime: "application/vnd.ms-appx.blockmap+xml".into(),
57                },
58                Rule::Override {
59                    part_name: "/AppxSignature.p7x".into(),
60                    mime: "application/vnd.ms-appx.signature".into(),
61                },
62            ],
63        }
64    }
65}
66
67#[derive(Clone, Debug, Deserialize, Serialize)]
68pub enum Rule {
69    Default {
70        #[serde(rename(serialize = "Extension"))]
71        ext: String,
72        #[serde(rename(serialize = "ContentType"))]
73        mime: String,
74    },
75    Override {
76        #[serde(rename(serialize = "PartName"))]
77        part_name: String,
78        #[serde(rename(serialize = "ContentType"))]
79        mime: String,
80    },
81}
82
83fn default_namespace() -> String {
84    "http://schemas.openxmlformats.org/package/2006/content-types".into()
85}