1use hard_xml::{XmlRead, XmlResult, XmlWrite, XmlWriter};
6use std::borrow::Cow;
7use std::io::Write;
8
9use crate::schema::{SCHEMA_CORE_2, SCHEMA_DC, SCHEMA_DCTERMS, 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 #[xml(flatten_text = "dcterms:created")]
37 pub created: Option<Cow<'a, str>>,
38 #[xml(flatten_text = "dcterms:modified")]
39 pub modified: Option<Cow<'a, str>>,
40 #[xml(flatten_text = "cp:contentStatus")]
41 pub content_status: Option<Cow<'a, str>>,
42 #[xml(flatten_text = "dc:language")]
43 pub language: Option<Cow<'a, str>>,
44 #[xml(flatten_text = "cp:category")]
45 pub category: Option<Cow<'a, str>>,
46}
47
48#[derive(Debug, Default, XmlRead, Clone)]
49#[xml(tag = "coreProperties")]
50pub struct CoreNoNamespace<'a> {
51 #[xml(flatten_text = "dc:title")]
52 pub title: Option<Cow<'a, str>>,
53 #[xml(flatten_text = "dc:subject")]
54 pub subject: Option<Cow<'a, str>>,
55 #[xml(flatten_text = "dc:creator")]
56 pub creator: Option<Cow<'a, str>>,
57 #[xml(flatten_text = "keywords")]
58 pub keywords: Option<Cow<'a, str>>,
59 #[xml(flatten_text = "dc:description")]
60 pub description: Option<Cow<'a, str>>,
61 #[xml(flatten_text = "lastModifiedBy")]
62 pub last_modified_by: Option<Cow<'a, str>>,
63 #[xml(flatten_text = "revision")]
64 pub revision: Option<Cow<'a, str>>,
65 #[xml(flatten_text = "created")]
66 pub created: Option<Cow<'a, str>>,
67 #[xml(flatten_text = "modified")]
68 pub modified: Option<Cow<'a, str>>,
69 #[xml(flatten_text = "contentStatus")]
70 pub content_status: Option<Cow<'a, str>>,
71 #[xml(flatten_text = "language")]
72 pub language: Option<Cow<'a, str>>,
73 #[xml(flatten_text = "category")]
74 pub category: Option<Cow<'a, str>>,
75}
76
77impl<'a> XmlWrite for CoreNamespace<'a> {
78 fn to_writer<W: Write>(&self, writer: &mut XmlWriter<W>) -> XmlResult<()> {
79 let CoreNamespace {
80 title,
81 subject,
82 creator,
83 keywords,
84 description,
85 last_modified_by,
86 revision,
87 created,
88 modified,
89 content_status,
90 language,
91 category,
92 } = self;
93
94 log::debug!("[Core] Started writing.");
95 let _ = write!(writer.inner, "{}", SCHEMA_XML);
96
97 writer.write_element_start("cp:coreProperties")?;
98
99 writer.write_attribute("xmlns:cp", SCHEMA_CORE_2)?;
100
101 writer.write_attribute("xmlns:dc", SCHEMA_DC)?;
102
103 writer.write_attribute("xmlns:dcterms", SCHEMA_DCTERMS)?;
104
105 if title.is_none()
106 && subject.is_none()
107 && creator.is_none()
108 && keywords.is_none()
109 && description.is_none()
110 && last_modified_by.is_none()
111 && revision.is_none()
112 && created.is_none()
113 && modified.is_none()
114 && content_status.is_none()
115 && language.is_none()
116 && category.is_none()
117 {
118 writer.write_element_end_empty()?;
119 } else {
120 writer.write_element_end_open()?;
121 if let Some(val) = title {
122 writer.write_flatten_text("dc:title", val, false)?;
123 }
124 if let Some(val) = subject {
125 writer.write_flatten_text("dc:subject", val, false)?;
126 }
127 if let Some(val) = creator {
128 writer.write_flatten_text("dc:creator", val, false)?;
129 }
130 if let Some(val) = keywords {
131 writer.write_flatten_text("cp:keywords", val, false)?;
132 }
133 if let Some(val) = description {
134 writer.write_flatten_text("dc:description", val, false)?;
135 }
136 if let Some(val) = last_modified_by {
137 writer.write_flatten_text("cp:lastModifiedBy", val, false)?;
138 }
139 if let Some(val) = revision {
140 writer.write_flatten_text("cp:revision", val, false)?;
141 }
142 if let Some(val) = revision {
143 writer.write_flatten_text("cp:revision", val, false)?;
144 }
145 if let Some(val) = created {
146 writer.write_flatten_text("dcterms:created", val, false)?;
147 }
148 if let Some(val) = modified {
149 writer.write_flatten_text("dcterms:modified", val, false)?;
150 }
151 if let Some(val) = content_status {
152 writer.write_flatten_text("cp:contentStatus", val, false)?;
153 }
154 if let Some(val) = language {
155 writer.write_flatten_text("dc:language", val, false)?;
156 }
157 if let Some(val) = category {
158 writer.write_flatten_text("cp:category", val, false)?;
159 }
160 writer.write_element_end_close("cp:coreProperties")?;
161 }
162
163 log::debug!("[Core] Finished writing.");
164
165 Ok(())
166 }
167}
168
169impl<'a> XmlWrite for CoreNoNamespace<'a> {
170 fn to_writer<W: Write>(&self, writer: &mut XmlWriter<W>) -> XmlResult<()> {
171 let CoreNoNamespace {
172 title,
173 subject,
174 creator,
175 keywords,
176 description,
177 last_modified_by,
178 revision,
179 created,
180 modified,
181 content_status,
182 language,
183 category,
184 } = self;
185
186 log::debug!("[Core] Started writing.");
187 let _ = write!(writer.inner, "{}", SCHEMA_XML);
188
189 writer.write_element_start("cp:coreProperties")?;
190
191 writer.write_attribute("xmlns:cp", SCHEMA_CORE_2)?;
192
193 writer.write_attribute("xmlns:dc", SCHEMA_DC)?;
194
195 if title.is_none()
196 && subject.is_none()
197 && creator.is_none()
198 && keywords.is_none()
199 && description.is_none()
200 && last_modified_by.is_none()
201 && revision.is_none()
202 {
203 writer.write_element_end_empty()?;
204 } else {
205 writer.write_element_end_open()?;
206 if let Some(val) = title {
207 writer.write_flatten_text("dc:title", val, false)?;
208 }
209 if let Some(val) = subject {
210 writer.write_flatten_text("dc:subject", val, false)?;
211 }
212 if let Some(val) = creator {
213 writer.write_flatten_text("dc:creator", val, false)?;
214 }
215 if let Some(val) = keywords {
216 writer.write_flatten_text("cp:keywords", val, false)?;
217 }
218 if let Some(val) = description {
219 writer.write_flatten_text("dc:description", val, false)?;
220 }
221 if let Some(val) = last_modified_by {
222 writer.write_flatten_text("cp:lastModifiedBy", val, false)?;
223 }
224 if let Some(val) = revision {
225 writer.write_flatten_text("cp:revision", val, false)?;
226 }
227 if let Some(val) = created {
228 writer.write_flatten_text("dcterms:created", val, false)?;
229 }
230 if let Some(val) = modified {
231 writer.write_flatten_text("dcterms:modified", val, false)?;
232 }
233 if let Some(val) = content_status {
234 writer.write_flatten_text("cp:contentStatus", val, false)?;
235 }
236 if let Some(val) = language {
237 writer.write_flatten_text("dc:language", val, false)?;
238 }
239 if let Some(val) = category {
240 writer.write_flatten_text("cp:category", val, false)?;
241 }
242 writer.write_element_end_close("cp:coreProperties")?;
243 }
244
245 log::debug!("[Core] Finished writing.");
246
247 Ok(())
248 }
249}