docx_rust/
core.rs

1//! Core File Properties part
2//!
3//! The corresponding ZIP item is `/docProps/core.xml`.
4
5use hard_xml::{XmlRead, XmlResult, XmlWrite, XmlWriter};
6use std::borrow::Cow;
7use std::io::Write;
8
9use crate::schema::{SCHEMA_CORE_2, SCHEMA_DC, SCHEMA_XML};
10
11#[derive(Debug, XmlRead, XmlWrite, Clone)]
12pub enum Core<'a> {
13    #[xml(tag = "cp:coreProperties")]
14    CoreNamespace(CoreNamespace<'a>),
15    #[xml(tag = "coreProperties")]
16    CoreNoNamespace(CoreNoNamespace<'a>),
17}
18
19#[derive(Debug, Default, XmlRead, Clone)]
20#[xml(tag = "cp:coreProperties")]
21pub struct CoreNamespace<'a> {
22    #[xml(flatten_text = "dc:title")]
23    pub title: Option<Cow<'a, str>>,
24    #[xml(flatten_text = "dc:subject")]
25    pub subject: Option<Cow<'a, str>>,
26    #[xml(flatten_text = "dc:creator")]
27    pub creator: Option<Cow<'a, str>>,
28    #[xml(flatten_text = "cp:keywords")]
29    pub keywords: Option<Cow<'a, str>>,
30    #[xml(flatten_text = "dc:description")]
31    pub description: Option<Cow<'a, str>>,
32    #[xml(flatten_text = "cp:lastModifiedBy")]
33    pub last_modified_by: Option<Cow<'a, str>>,
34    #[xml(flatten_text = "cp:revision")]
35    pub revision: Option<Cow<'a, str>>,
36}
37
38#[derive(Debug, Default, XmlRead, Clone)]
39#[xml(tag = "coreProperties")]
40pub struct CoreNoNamespace<'a> {
41    #[xml(flatten_text = "dc:title")]
42    pub title: Option<Cow<'a, str>>,
43    #[xml(flatten_text = "dc:subject")]
44    pub subject: Option<Cow<'a, str>>,
45    #[xml(flatten_text = "dc:creator")]
46    pub creator: Option<Cow<'a, str>>,
47    #[xml(flatten_text = "keywords")]
48    pub keywords: Option<Cow<'a, str>>,
49    #[xml(flatten_text = "dc:description")]
50    pub description: Option<Cow<'a, str>>,
51    #[xml(flatten_text = "lastModifiedBy")]
52    pub last_modified_by: Option<Cow<'a, str>>,
53    #[xml(flatten_text = "revision")]
54    pub revision: Option<Cow<'a, str>>,
55}
56
57impl<'a> XmlWrite for CoreNamespace<'a> {
58    fn to_writer<W: Write>(&self, writer: &mut XmlWriter<W>) -> XmlResult<()> {
59        let CoreNamespace {
60            title,
61            subject,
62            creator,
63            keywords,
64            description,
65            last_modified_by,
66            revision,
67        } = self;
68
69        log::debug!("[Core] Started writing.");
70        let _ = write!(writer.inner, "{}", SCHEMA_XML);
71
72        writer.write_element_start("cp:coreProperties")?;
73
74        writer.write_attribute("xmlns:cp", SCHEMA_CORE_2)?;
75
76        writer.write_attribute("xmlns:dc", SCHEMA_DC)?;
77
78        if title.is_none()
79            && subject.is_none()
80            && creator.is_none()
81            && keywords.is_none()
82            && description.is_none()
83            && last_modified_by.is_none()
84            && revision.is_none()
85        {
86            writer.write_element_end_empty()?;
87        } else {
88            writer.write_element_end_open()?;
89            if let Some(val) = title {
90                writer.write_flatten_text("dc:title", val, false)?;
91            }
92            if let Some(val) = subject {
93                writer.write_flatten_text("dc:subject", val, false)?;
94            }
95            if let Some(val) = creator {
96                writer.write_flatten_text("dc:creator", val, false)?;
97            }
98            if let Some(val) = keywords {
99                writer.write_flatten_text("cp:keywords", val, false)?;
100            }
101            if let Some(val) = description {
102                writer.write_flatten_text("dc:description", val, false)?;
103            }
104            if let Some(val) = last_modified_by {
105                writer.write_flatten_text("cp:lastModifiedBy", val, false)?;
106            }
107            if let Some(val) = revision {
108                writer.write_flatten_text("cp:revision", val, false)?;
109            }
110            writer.write_element_end_close("cp:coreProperties")?;
111        }
112
113        log::debug!("[Core] Finished writing.");
114
115        Ok(())
116    }
117}
118
119impl<'a> XmlWrite for CoreNoNamespace<'a> {
120    fn to_writer<W: Write>(&self, writer: &mut XmlWriter<W>) -> XmlResult<()> {
121        let CoreNoNamespace {
122            title,
123            subject,
124            creator,
125            keywords,
126            description,
127            last_modified_by,
128            revision,
129        } = self;
130
131        log::debug!("[Core] Started writing.");
132        let _ = write!(writer.inner, "{}", SCHEMA_XML);
133
134        writer.write_element_start("cp:coreProperties")?;
135
136        writer.write_attribute("xmlns:cp", SCHEMA_CORE_2)?;
137
138        writer.write_attribute("xmlns:dc", SCHEMA_DC)?;
139
140        if title.is_none()
141            && subject.is_none()
142            && creator.is_none()
143            && keywords.is_none()
144            && description.is_none()
145            && last_modified_by.is_none()
146            && revision.is_none()
147        {
148            writer.write_element_end_empty()?;
149        } else {
150            writer.write_element_end_open()?;
151            if let Some(val) = title {
152                writer.write_flatten_text("dc:title", val, false)?;
153            }
154            if let Some(val) = subject {
155                writer.write_flatten_text("dc:subject", val, false)?;
156            }
157            if let Some(val) = creator {
158                writer.write_flatten_text("dc:creator", val, false)?;
159            }
160            if let Some(val) = keywords {
161                writer.write_flatten_text("cp:keywords", val, false)?;
162            }
163            if let Some(val) = description {
164                writer.write_flatten_text("dc:description", val, false)?;
165            }
166            if let Some(val) = last_modified_by {
167                writer.write_flatten_text("cp:lastModifiedBy", val, false)?;
168            }
169            if let Some(val) = revision {
170                writer.write_flatten_text("cp:revision", val, false)?;
171            }
172            writer.write_element_end_close("cp:coreProperties")?;
173        }
174
175        log::debug!("[Core] Finished writing.");
176
177        Ok(())
178    }
179}