docx_rust/document/
table_row.rs

1#![allow(unused_must_use)]
2use std::borrow::{Borrow, Cow};
3
4use super::SDT;
5
6use hard_xml::{XmlRead, XmlWrite};
7
8use crate::{__setter, __xml_test_suites, document::TableCell, formatting::TableRowProperty};
9
10/// Table Row
11///
12/// ```rust
13/// use docx_rust::document::*;
14/// use docx_rust::formatting::*;
15///
16/// let row = TableRow::default()
17///     .property(TableRowProperty::default())
18///     .push_cell(Paragraph::default())
19///     .push_cell(
20///         TableCell::paragraph(Paragraph::default())
21///             .property(TableCellProperty::default())
22///     );
23/// ```
24#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
25#[cfg_attr(test, derive(PartialEq))]
26#[xml(tag = "w:tr")]
27pub struct TableRow<'a> {
28    #[xml(default, child = "w:trPr")]
29    pub property: TableRowProperty,
30    #[xml(child = "w:tc", child = "w:sdt")]
31    pub cells: Vec<TableRowContent<'a>>,
32}
33
34#[derive(Debug, XmlRead, XmlWrite, Clone)]
35#[cfg_attr(test, derive(PartialEq))]
36pub enum TableRowContent<'a> {
37    #[xml(tag = "w:tc")]
38    TableCell(TableCell<'a>),
39    #[xml(tag = "w:sdt")]
40    SDT(SDT<'a>),
41}
42
43impl<'a> From<TableCell<'a>> for TableRowContent<'a> {
44    fn from(value: TableCell<'a>) -> Self {
45        TableRowContent::TableCell(value)
46    }
47}
48
49impl<'a> From<crate::document::Paragraph<'a>> for TableRowContent<'a> {
50    fn from(value: crate::document::Paragraph<'a>) -> Self {
51        let tc = TableCell::paragraph(value);
52        TableRowContent::TableCell(tc)
53    }
54}
55
56impl<'a> TableRow<'a> {
57    __setter!(property: TableRowProperty);
58
59    pub fn push_cell<T: Into<TableRowContent<'a>>>(mut self, cell: T) -> Self {
60        self.cells.push(cell.into());
61        self
62    }
63
64    pub fn iter_text(&self) -> impl Iterator<Item = &Cow<'a, str>> {
65        self.cells
66            .iter()
67            .filter_map(|content| match content {
68                //Some(content.iter_text())
69                TableRowContent::TableCell(tc) => Some(tc.iter_text()),
70                TableRowContent::SDT(_) => None,
71            })
72            .flatten()
73    }
74
75    pub fn iter_text_mut(&mut self) -> impl Iterator<Item = &mut Cow<'a, str>> {
76        self.cells
77            .iter_mut()
78            .filter_map(|content| match content {
79                //Some(content.iter_text_mut())
80                TableRowContent::TableCell(tc) => Some(tc.iter_text_mut()),
81                TableRowContent::SDT(_) => None,
82            })
83            .flatten()
84    }
85
86    pub fn replace_text<'b, I, T, S>(&mut self, dic: T) -> crate::DocxResult<()>
87    where
88        S: AsRef<str> + 'b,
89        T: IntoIterator<Item = I> + Copy,
90        I: Borrow<(S, S)>,
91    {
92        for cell in self.cells.iter_mut() {
93            if let TableRowContent::TableCell(c) = cell {
94                c.replace_text(dic)?
95            }
96        }
97        Ok(())
98    }
99}
100
101#[cfg(test)]
102use crate::document::Paragraph;
103
104__xml_test_suites!(
105    TableRow,
106    TableRow::default(),
107    "<w:tr><w:trPr/></w:tr>",
108    TableRow::default().push_cell(Paragraph::default()),
109    r#"<w:tr><w:trPr/><w:tc><w:tcPr><w:vAlign w:val="top"/></w:tcPr><w:p/></w:tc></w:tr>"#,
110);