docx_rs/documents/
document_rels.rs1use serde::Serialize;
2use std::io::Write;
3
4use super::*;
5use crate::documents::BuildXML;
6use crate::{escape::*, xml_builder::*};
7
8#[derive(Debug, Clone, PartialEq, Serialize, Default)]
9#[serde(rename_all = "camelCase")]
10pub struct DocumentRels {
11 pub has_comments: bool,
12 pub has_numberings: bool,
13 pub has_footnotes: bool,
14 pub images: Vec<(String, String)>,
15 pub hyperlinks: Vec<(String, String, String)>,
16 pub custom_xml_count: usize,
17 pub header_count: usize,
18 pub footer_count: usize,
19}
20
21impl DocumentRels {
22 pub fn new() -> DocumentRels {
23 Default::default()
24 }
25
26 pub fn add_custom_item(mut self) -> Self {
27 self.custom_xml_count += 1;
28 self
29 }
30
31 pub fn add_image(mut self, id: impl Into<String>, path: impl Into<String>) -> Self {
32 self.images.push((id.into(), path.into()));
33 self
34 }
35
36 pub fn add_hyperlinks(
37 mut self,
38 id: impl Into<String>,
39 path: impl Into<String>,
40 r#type: impl Into<String>,
41 ) -> Self {
42 self.hyperlinks
43 .push((id.into(), escape(&path.into()), r#type.into()));
44 self
45 }
46}
47
48impl BuildXML for DocumentRels {
49 fn build_to<W: Write>(
50 &self,
51 stream: xml::writer::EventWriter<W>,
52 ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
53 XMLBuilder::from(stream)
54 .declaration(None)?
55 .open_relationships("http://schemas.openxmlformats.org/package/2006/relationships")?
56 .relationship(
57 "rId1",
58 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
59 "styles.xml",
60 )?
61 .relationship(
62 "rId2",
63 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable",
64 "fontTable.xml",
65 )?
66 .relationship(
67 "rId3",
68 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings",
69 "settings.xml",
70 )?
71 .relationship(
72 "rId5",
73 "http://schemas.microsoft.com/office/2011/relationships/commentsExtended",
74 "commentsExtended.xml",
75 )?
76 .apply_if(self.has_comments, |b| {
77 b.relationship(
78 "rId6",
79 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
80 "comments.xml",
81 )
82 })?
83 .apply_if(self.has_numberings, |b| {
84 b.relationship(
85 "rId7",
86 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",
87 "numbering.xml",
88 )
89 })?
90 .apply_if(self.has_footnotes, |b| {
91 b.relationship(
92 "rId8",
93 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
94 "footnotes.xml",
95 )
96 })?
97 .apply_each(0..self.header_count, |i, b| {
98 b.relationship(
99 &create_header_rid(i + 1),
100 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
101 &format!("header{}.xml", i + 1),
102 )
103 })?
104 .apply_each(0..self.footer_count, |i, b| {
105 b.relationship(
106 &create_footer_rid(i + 1),
107 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
108 &format!("footer{}.xml", i + 1),
109 )
110 })?
111 .apply_each(0..self.custom_xml_count, |i, b| {
112 b.relationship(
113 &format!("rId{}", i + 8),
114 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml",
115 &format!("../customXml/item{}.xml", i + 1),
116 )
117 })?
118 .apply_each(self.images.iter(), |(id, path), b| {
119 b.relationship(
120 id,
121 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
122 path,
123 )
124 })?
125 .apply_each(self.hyperlinks.iter(), |(id, path, r#type), b| {
126 b.relationship_with_mode(
127 id,
128 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
129 path,
130 r#type,
131 )
132 })?
133 .close()?
134 .into_inner()
135 }
136}