docx_rs/documents/doc_props/
core.rs

1use serde::Serialize;
2use std::io::Write;
3
4use crate::documents::BuildXML;
5use crate::xml_builder::*;
6
7#[derive(Debug, Clone, PartialEq, Serialize, Default)]
8#[serde(rename_all = "camelCase")]
9pub struct CoreProps {
10    config: CorePropsConfig,
11}
12
13#[derive(Debug, Clone, PartialEq, Serialize, Default)]
14#[serde(rename_all = "camelCase")]
15pub struct CorePropsConfig {
16    created: Option<String>,
17    creator: Option<String>,
18    description: Option<String>,
19    language: Option<String>,
20    last_modified_by: Option<String>,
21    modified: Option<String>,
22    revision: Option<usize>,
23    subject: Option<String>,
24    title: Option<String>,
25}
26
27impl CoreProps {
28    pub(crate) fn new(config: CorePropsConfig) -> CoreProps {
29        CoreProps { config }
30    }
31
32    pub fn created_at(mut self, date: &str) -> Self {
33        self.config.created = Some(date.to_owned());
34        self
35    }
36
37    pub fn updated_at(mut self, date: &str) -> Self {
38        self.config.modified = Some(date.to_owned());
39        self
40    }
41}
42
43impl CorePropsConfig {
44    pub fn new() -> Self {
45        CorePropsConfig {
46            created: None,
47            creator: None,
48            description: None,
49            language: None,
50            last_modified_by: None,
51            modified: None,
52            revision: None,
53            subject: None,
54            title: None,
55        }
56    }
57}
58
59impl BuildXML for CoreProps {
60    fn build_to<W: Write>(
61        &self,
62        stream: xml::writer::EventWriter<W>,
63    ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
64        XMLBuilder::from(stream)
65            .declaration(Some(true))?
66            .open_core_properties(
67                "http://schemas.openxmlformats.org/package/2006/metadata/core-properties",
68                "http://purl.org/dc/elements/1.1/",
69                "http://purl.org/dc/terms/",
70                "http://purl.org/dc/dcmitype/",
71                "http://www.w3.org/2001/XMLSchema-instance",
72            )?
73            .dcterms_created(
74                "dcterms:W3CDTF",
75                self.config
76                    .created
77                    .as_deref()
78                    .unwrap_or("1970-01-01T00:00:00Z"),
79            )?
80            .dc_creator(self.config.creator.as_deref().unwrap_or("unknown"))?
81            .cp_last_modified_by(self.config.last_modified_by.as_deref().unwrap_or("unknown"))?
82            .dcterms_modified(
83                "dcterms:W3CDTF",
84                self.config
85                    .modified
86                    .as_deref()
87                    .unwrap_or("1970-01-01T00:00:00Z"),
88            )?
89            .cp_revision(&self.config.revision.unwrap_or(1).to_string())?
90            .apply_opt(self.config.description.as_ref(), |v, b| b.dc_description(v))?
91            .apply_opt(self.config.language.as_ref(), |v, b| b.dc_language(v))?
92            .apply_opt(self.config.subject.as_ref(), |v, b| b.dc_subject(v))?
93            .apply_opt(self.config.title.as_ref(), |v, b| b.dc_title(v))?
94            .close()?
95            .into_inner()
96    }
97}
98
99#[cfg(test)]
100mod tests {
101
102    use super::*;
103    #[cfg(test)]
104    use pretty_assertions::assert_eq;
105    use std::str;
106
107    #[test]
108    fn test_default_doc_props_core() {
109        let c = CoreProps::new(CorePropsConfig {
110            created: None,
111            creator: None,
112            description: None,
113            language: None,
114            last_modified_by: None,
115            modified: None,
116            revision: None,
117            subject: None,
118            title: None,
119        });
120        let b = c.build();
121        assert_eq!(
122            str::from_utf8(&b).unwrap(),
123            r#"<?xml version="1.0" encoding="UTF-8" standalone="yes"?><cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dcterms:created xsi:type="dcterms:W3CDTF">1970-01-01T00:00:00Z</dcterms:created><dc:creator>unknown</dc:creator><cp:lastModifiedBy>unknown</cp:lastModifiedBy><dcterms:modified xsi:type="dcterms:W3CDTF">1970-01-01T00:00:00Z</dcterms:modified><cp:revision>1</cp:revision></cp:coreProperties>"#
124        );
125    }
126
127    #[test]
128    fn test_configured_doc_props_core_build() {
129        let c = CoreProps::new(CorePropsConfig {
130            created: Some("2019-01-01".to_owned()),
131            creator: Some("foo".to_owned()),
132            description: Some("bar".to_owned()),
133            language: Some("en".to_owned()),
134            last_modified_by: Some("go".to_owned()),
135            modified: Some("2019-01-01".to_owned()),
136            revision: Some(1),
137            subject: Some("subject".to_owned()),
138            title: Some("title".to_owned()),
139        });
140        let b = c.build();
141        assert_eq!(
142            str::from_utf8(&b).unwrap(),
143            r#"<?xml version="1.0" encoding="UTF-8" standalone="yes"?><cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dcterms:created xsi:type="dcterms:W3CDTF">2019-01-01</dcterms:created><dc:creator>foo</dc:creator><cp:lastModifiedBy>go</cp:lastModifiedBy><dcterms:modified xsi:type="dcterms:W3CDTF">2019-01-01</dcterms:modified><cp:revision>1</cp:revision><dc:description>bar</dc:description><dc:language>en</dc:language><dc:subject>subject</dc:subject><dc:title>title</dc:title></cp:coreProperties>"#
144        );
145    }
146}