#[cfg(test)]
mod tests;
use crate::workbook::DocProperties;
use crate::{Result, XmlWritable, XmlWriter};
use chrono::{DateTime, Utc};
use indexmap::indexmap;
pub(crate) struct Core<'a> {
pub properties: &'a DocProperties,
}
impl XmlWritable for Core<'_> {
fn write_xml<W: XmlWriter>(&self, w: &mut W) -> Result<()> {
let tag = "cp:coreProperties";
let attrs = indexmap! {
"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",
};
w.start_tag_with_attrs(tag, attrs)?;
self.write_dc_title(w)?;
self.write_dc_subject(w)?;
self.write_dc_creator(w)?;
self.write_cp_keywords(w)?;
self.write_dc_description(w)?;
self.write_cp_last_modified_by(w)?;
self.write_dcterms_created(w)?;
self.write_dcterms_modified(w)?;
self.write_cp_category(w)?;
self.write_cp_content_status(w)?;
w.end_tag(tag)?;
Ok(())
}
}
impl Core<'_> {
fn write_if_not_empty<W: XmlWriter>(
w: &mut W,
tag: &str,
string: &str,
) -> Result<()> {
if !string.is_empty() {
w.tag_with_text(tag, string)?;
}
Ok(())
}
fn write_dc_title<W: XmlWriter>(&self, w: &mut W) -> Result<()> {
Self::write_if_not_empty(w, "dc:title", &self.properties.title)
}
fn write_dc_subject<W: XmlWriter>(&self, w: &mut W) -> Result<()> {
Self::write_if_not_empty(w, "dc:subject", &self.properties.subject)
}
fn write_dc_creator<W: XmlWriter>(&self, w: &mut W) -> Result<()> {
w.tag_with_text("dc:creator", &self.properties.author)
}
fn write_cp_keywords<W: XmlWriter>(&self, w: &mut W) -> Result<()> {
Self::write_if_not_empty(
w,
"cp:keywords",
&self.properties.keywords,
)
}
fn write_dc_description<W: XmlWriter>(&self, w: &mut W) -> Result<()> {
Self::write_if_not_empty(
w,
"dc:description",
&self.properties.comments,
)
}
fn write_cp_last_modified_by<W: XmlWriter>(
&self,
w: &mut W,
) -> Result<()> {
w.tag_with_text("cp:lastModifiedBy", &self.properties.author)
}
fn write_dcterms_created<W: XmlWriter>(
&self,
w: &mut W,
) -> Result<()> {
let tag = "dcterms:created";
let attrs = indexmap! {"xsi:type" => "dcterms:W3CDTF"};
let text = self
.properties
.created
.clone()
.unwrap_or_else(Utc::now)
.formatted();
w.tag_with_attrs_and_text(tag, attrs, &text)
}
fn write_dcterms_modified<W: XmlWriter>(
&self,
w: &mut W,
) -> Result<()> {
let tag = "dcterms:modified";
let attrs = indexmap! {"xsi:type" => "dcterms:W3CDTF"};
let text = self
.properties
.created
.clone()
.unwrap_or_else(Utc::now)
.formatted();
w.tag_with_attrs_and_text(tag, attrs, &text)
}
fn write_cp_category<W: XmlWriter>(&self, w: &mut W) -> Result<()> {
Self::write_if_not_empty(
w,
"cp:category",
&self.properties.category,
)
}
fn write_cp_content_status<W: XmlWriter>(
&self,
w: &mut W,
) -> Result<()> {
Self::write_if_not_empty(
w,
"cp:contentStatus",
&self.properties.status,
)
}
}
trait Formatted {
fn formatted(&self) -> String;
}
impl Formatted for DateTime<Utc> {
fn formatted(&self) -> String {
self.format("%Y-%m-%dT%H:%M:%SZ").to_string()
}
}