#[cfg(test)]
mod tests;
use crate::{
Result, XmlWritable, XmlWriter, SCHEMA_DOCUMENT, SCHEMA_MS,
SCHEMA_PACKAGE,
};
use indexmap::indexmap;
#[derive(Debug)]
pub(crate) struct Relationship {
pub relation_id: usize,
pub relation_type: String,
pub target: String,
pub target_mode: Option<String>,
}
#[derive(Default, Debug)]
pub(crate) struct Relationships {
pub entries: Vec<Relationship>,
}
impl Relationships {
pub fn add_document_relationship(
&mut self,
relation_type: &str,
target: impl Into<String>,
) {
self.add_relationship(
SCHEMA_DOCUMENT,
relation_type,
target.into(),
None,
);
}
pub fn add_package_relationship(
&mut self,
relation_type: &str,
target: impl Into<String>,
) {
self.add_relationship(
SCHEMA_PACKAGE,
relation_type,
target.into(),
None,
);
}
pub fn add_ms_package_relationship(
&mut self,
relation_type: &str,
target: impl Into<String>,
) {
self.add_relationship(
SCHEMA_MS,
relation_type,
target.into(),
None,
);
}
pub fn add_worksheet_relationship(
&mut self,
relation_type: &str,
target: impl Into<String>,
target_mode: impl Into<String>,
) {
self.add_relationship(
SCHEMA_DOCUMENT,
relation_type,
target.into(),
Some(target_mode.into()),
);
}
fn add_relationship(
&mut self,
schema: &str,
relation_type: &str,
target: String,
target_mode: Option<String>,
) {
self.entries.push(Relationship {
relation_id: self.entries.len() + 1,
relation_type: format!("{}{}", schema, relation_type),
target,
target_mode,
});
}
}
impl XmlWritable for Relationships {
fn write_xml<W: XmlWriter>(&self, w: &mut W) -> Result<()> {
let tag = "Relationships";
let attrs = indexmap! {
"xmlns" =>
"http://schemas.openxmlformats.org/package/2006/relationships",
};
w.start_tag_with_attrs(tag, attrs)?;
for relationship in self.entries.iter() {
relationship.write_xml(w)?;
}
w.end_tag(tag)?;
Ok(())
}
}
impl XmlWritable for Relationship {
fn write_xml<W: XmlWriter>(&self, w: &mut W) -> Result<()> {
let relation_id = format!("rId{}", self.relation_id);
let mut attrs = indexmap! {
"Id" => relation_id.as_str(),
"Type"=> self.relation_type.as_str(),
"Target"=> &self.target.as_str(),
};
if let Some(ref target_mode) = self.target_mode {
attrs.insert("TargetMode", target_mode.as_str());
}
w.empty_tag_with_attrs("Relationship", attrs)
}
}