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