1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use derive_more::From;
use strong_xml::{XmlRead, XmlWrite};
use crate::__xml_test_suites;
use crate::document::{Paragraph, Table};
use crate::formatting::SectionProperty;
use super::SDT;
#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
#[cfg_attr(test, derive(PartialEq))]
#[xml(tag = "w:body")]
pub struct Body<'a> {
#[xml(child = "w:p", child = "w:tbl", child = "w:sectPr", child = "w:sdt")]
pub content: Vec<BodyContent<'a>>,
}
impl<'a> Body<'a> {
pub fn push<T: Into<BodyContent<'a>>>(&mut self, content: T) -> &mut Self {
self.content.push(content.into());
self
}
pub fn text(&self) -> String {
let v: Vec<_> = self
.content
.iter()
.filter_map(|content| match content {
BodyContent::Paragraph(para) => Some(para.iter_text()),
BodyContent::Table(_) => None,
BodyContent::SectionProperty(_) => None,
BodyContent::Sdt(_) => None,
})
.flatten()
.map(|t| t.to_string())
.collect();
v.join("")
}
pub fn replace_text_simple<S>(&mut self, old: S, new: S)
where
S: AsRef<str>,
{
let dic = (old, new);
let dic = vec![dic];
let _d = self.replace_text(&dic);
}
pub fn replace_text<'b, T, S>(&mut self, dic: T) -> crate::DocxResult<()>
where
S: AsRef<str> + 'b,
T: IntoIterator<Item = &'b (S, S)> + std::marker::Copy,
{
for content in self.content.iter_mut() {
match content {
BodyContent::Paragraph(p) => {
p.replace_text(dic)?;
}
BodyContent::Table(_) => {}
BodyContent::SectionProperty(_) => {}
BodyContent::Sdt(_) => {}
}
}
Ok(())
}
}
#[derive(Debug, From, XmlRead, XmlWrite, Clone)]
#[cfg_attr(test, derive(PartialEq))]
pub enum BodyContent<'a> {
#[xml(tag = "w:p")]
Paragraph(Paragraph<'a>),
#[xml(tag = "w:tbl")]
Table(Table<'a>),
#[xml(tag = "w:sdt")]
Sdt(SDT<'a>),
#[xml(tag = "w:sectPr")]
SectionProperty(SectionProperty<'a>),
}
__xml_test_suites!(
Body,
Body::default(),
r#"<w:body/>"#,
Body {
content: vec![Paragraph::default().into()]
},
r#"<w:body><w:p/></w:body>"#,
Body {
content: vec![Table::default().into()]
},
r#"<w:body><w:tbl><w:tblPr/></w:tbl></w:body>"#,
);