docx_rs/documents/
rels.rs1use serde::{Deserialize, Serialize};
2use std::io::Write;
3
4use crate::documents::BuildXML;
5use crate::xml_builder::*;
6
7#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)]
8pub struct Rels {
9 pub rels: Vec<(String, String, String)>,
10}
11
12impl Rels {
13 pub fn new() -> Rels {
14 Default::default()
15 }
16
17 pub fn set_default(mut self) -> Self {
18 self.rels.push((
19 "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"
20 .to_owned(),
21 "rId1".to_owned(),
22 "docProps/core.xml".to_owned(),
23 ));
24 self.rels.push(
25 ("http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties".to_owned(),
26 "rId2".to_owned(), "docProps/app.xml".to_owned()),
27 );
28 self.rels.push((
29 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
30 .to_owned(),
31 "rId3".to_owned(),
32 "word/document.xml".to_owned(),
33 ));
34 self.rels.push((
35 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties"
36 .to_owned(),
37 "rId4".to_owned(),
38 "docProps/custom.xml".to_owned(),
39 ));
40 self
41 }
42
43 pub fn add_taskpanes_rel(mut self) -> Self {
44 self = self.add_rel(
45 "http://schemas.microsoft.com/office/2011/relationships/webextensiontaskpanes",
46 "word/webextensions/taskpanes.xml",
47 );
48 self
49 }
50
51 pub fn add_rel(mut self, rel_type: impl Into<String>, target: impl Into<String>) -> Self {
52 self.rels.push((
53 rel_type.into(),
54 format!("rId{}", self.rels.len() + 1),
55 target.into(),
56 ));
57 self
58 }
59
60 pub fn find_target(&self, rel_type: &str) -> Option<&(String, String, String)> {
61 self.rels.iter().find(|rel| rel.0 == rel_type)
62 }
63}
64
65impl BuildXML for Rels {
66 fn build_to<W: Write>(
67 &self,
68 stream: xml::writer::EventWriter<W>,
69 ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
70 XMLBuilder::from(stream)
71 .declaration(None)?
72 .open_relationships("http://schemas.openxmlformats.org/package/2006/relationships")?
73 .apply_each(&self.rels, |(k, id, v), b| b.relationship(id, k, v))?
74 .close()?
75 .into_inner()
76 }
77}
78
79#[cfg(test)]
80mod tests {
81
82 use super::*;
83 #[cfg(test)]
84 use pretty_assertions::assert_eq;
85 use std::str;
86
87 #[test]
88 fn test_build() {
89 let c = Rels::new().set_default();
90 let b = c.build();
91 assert_eq!(
92 str::from_utf8(&b).unwrap(),
93 r#"<?xml version="1.0" encoding="UTF-8"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml" /><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml" /><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml" /><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml" /></Relationships>"#
94 );
95 }
96}