karo 0.1.2

Spreadsheet export
Documentation
#[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)
    }
}