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_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}