rs_docx/document/
table_cell.rs1#![allow(unused_must_use)]
2use std::borrow::{Borrow, Cow};
3
4use derive_more::From;
5use hard_xml::{XmlRead, XmlWrite};
6
7use crate::{
8 __setter, __xml_test_suites, document::Paragraph, document::Table,
9 formatting::TableCellProperty,
10};
11
12#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
24#[cfg_attr(test, derive(PartialEq))]
25#[xml(tag = "w:tc")]
26pub struct TableCell<'a> {
27 #[xml(default, child = "w:tcPr")]
28 pub property: TableCellProperty,
29 #[xml(child = "w:p", child = "w:tbl")]
30 pub content: Vec<TableCellContent<'a>>,
31}
32
33impl<'a> TableCell<'a> {
34 __setter!(property: TableCellProperty);
35
36 pub fn paragraph<T: Into<Paragraph<'a>>>(par: T) -> Self {
37 TableCell {
38 property: TableCellProperty::default(),
39 content: vec![TableCellContent::Paragraph(par.into())],
40 }
41 }
42
43 pub fn iter_text(&self) -> Box<dyn Iterator<Item = &Cow<'a, str>> + '_> {
44 Box::new(self.content.iter().flat_map(|content| match content {
45 TableCellContent::Paragraph(p) => {
46 Box::new(p.iter_text()) as Box<dyn Iterator<Item = &Cow<'a, str>>>
47 }
48 TableCellContent::Table(t) => {
49 Box::new(t.iter_text()) as Box<dyn Iterator<Item = &Cow<'a, str>>>
50 }
51 }))
52 }
53
54 pub fn iter_text_mut(&mut self) -> Box<dyn Iterator<Item = &mut Cow<'a, str>> + '_> {
55 Box::new(self.content.iter_mut().flat_map(|content| match content {
56 TableCellContent::Paragraph(p) => {
57 Box::new(p.iter_text_mut()) as Box<dyn Iterator<Item = &mut Cow<'a, str>>>
58 }
59 TableCellContent::Table(t) => {
60 Box::new(t.iter_text_mut()) as Box<dyn Iterator<Item = &mut Cow<'a, str>>>
61 }
62 }))
63 }
64
65 pub fn replace_text<'b, I, T, S>(&mut self, dic: T) -> crate::DocxResult<()>
66 where
67 S: AsRef<str> + 'b,
68 T: IntoIterator<Item = I> + Copy,
69 I: Borrow<(S, S)>,
70 {
71 for content in self.content.iter_mut() {
72 match content {
73 TableCellContent::Paragraph(p) => p.replace_text(dic)?,
74 TableCellContent::Table(t) => t.replace_text(dic)?,
75 }
76 }
77 Ok(())
78 }
79}
80
81impl<'a, T: Into<TableCellContent<'a>>> From<T> for TableCell<'a> {
82 fn from(content: T) -> Self {
83 TableCell {
84 property: TableCellProperty::default(),
85 content: vec![content.into()],
86 }
87 }
88}
89
90#[derive(Debug, From, XmlRead, XmlWrite, Clone)]
91#[cfg_attr(test, derive(PartialEq))]
92#[allow(clippy::large_enum_variant)]
93pub enum TableCellContent<'a> {
94 #[xml(tag = "w:p")]
95 Paragraph(Paragraph<'a>),
96 #[xml(tag = "w:tbl")]
97 Table(Table<'a>),
98}
99
100__xml_test_suites!(
101 TableCell,
102 TableCell::paragraph(Paragraph::default()),
103 r#"<w:tc><w:tcPr><w:vAlign w:val="top"/></w:tcPr><w:p/></w:tc>"#,
104 TableCell::from(Table::default()),
105 r#"<w:tc><w:tcPr><w:vAlign w:val="top"/></w:tcPr><w:tbl><w:tblPr/><w:tblGrid/></w:tbl></w:tc>"#,
106);