docx_rs/reader/
table_cell.rs

1use std::io::Read;
2use std::str::FromStr;
3
4use xml::attribute::OwnedAttribute;
5use xml::reader::{EventReader, XmlEvent};
6
7use super::*;
8
9impl ElementReader for TableCell {
10    fn read<R: Read>(r: &mut EventReader<R>, _: &[OwnedAttribute]) -> Result<Self, ReaderError> {
11        let mut cell = TableCell::new();
12        loop {
13            let e = r.next();
14
15            match e {
16                Ok(XmlEvent::StartElement {
17                    attributes, name, ..
18                }) => {
19                    let e = XMLElement::from_str(&name.local_name).unwrap();
20                    match e {
21                        XMLElement::Paragraph => {
22                            let p = Paragraph::read(r, &attributes)?;
23                            cell = cell.add_paragraph(p);
24                            continue;
25                        }
26                        XMLElement::StructuredDataTag => {
27                            if let Ok(tag) = StructuredDataTag::read(r, &attributes) {
28                                cell = cell.add_structured_data_tag(tag);
29                            }
30                            continue;
31                        }
32                        XMLElement::TableCellProperty => {
33                            if let Ok(p) = TableCellProperty::read(r, &attributes) {
34                                cell.property = p;
35                            }
36                            continue;
37                        }
38                        XMLElement::Table => {
39                            if let Ok(table) = Table::read(r, &attributes) {
40                                cell = cell.add_table(table)
41                            }
42                        }
43                        _ => {}
44                    }
45                }
46                Ok(XmlEvent::EndElement { name, .. }) => {
47                    let e = XMLElement::from_str(&name.local_name).unwrap();
48                    if e == XMLElement::TableCell {
49                        return Ok(cell);
50                    }
51                }
52                Err(_) => return Err(ReaderError::XMLReadError),
53                _ => {}
54            }
55        }
56    }
57}
58
59#[cfg(test)]
60mod tests {
61
62    use super::*;
63    use crate::types::*;
64    #[cfg(test)]
65    use pretty_assertions::assert_eq;
66
67    #[test]
68    fn test_read_cell_with_prop() {
69        let c = r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
70<w:tc>
71    <w:tcPr>
72        <w:tcW w:w="6425" w:type="dxa"/>
73        <w:vMerge w:val="restart"/>
74        <w:gridSpan w:val="2"/>
75        <w:tcBorders>
76            <w:top w:val="single" w:sz="2" w:space="0" w:color="000000"/>
77            <w:left w:val="single" w:sz="3" w:space="0" w:color="000000"/>
78            <w:right w:val="single" w:sz="2" w:space="0" w:color="000000"/>
79            <w:bottom w:val="double" w:sz="4" w:space="0" w:color="000000"/>
80            <w:insideH w:val="single" w:sz="5" w:space="0" w:color="FF0000"/>
81            <w:insideV w:val="single" w:sz="2" w:space="0" w:color="000000"/>
82        </w:tcBorders>
83    </w:tcPr>
84    <w:p>
85        <w:r>
86            <w:rPr></w:rPr>
87        </w:r>
88    </w:p>
89</w:tc>
90</w:document>"#;
91        let mut parser = EventReader::new(c.as_bytes());
92        let cell = TableCell::read(&mut parser, &[]).unwrap();
93        assert_eq!(
94            cell,
95            TableCell::new()
96                .add_paragraph(Paragraph::new().add_run(Run::new()))
97                .width(6425, WidthType::Dxa)
98                .grid_span(2)
99                .vertical_merge(VMergeType::Restart)
100                .set_border(TableCellBorder::new(TableCellBorderPosition::Top))
101                .set_border(TableCellBorder::new(TableCellBorderPosition::Left).size(3))
102                .set_border(
103                    TableCellBorder::new(TableCellBorderPosition::Bottom)
104                        .size(4)
105                        .border_type(BorderType::Double)
106                )
107                .set_border(
108                    TableCellBorder::new(TableCellBorderPosition::InsideH)
109                        .size(5)
110                        .color("FF0000".to_owned())
111                )
112        );
113    }
114
115    #[test]
116    fn test_read_no_attr_vmerge() {
117        let c = r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
118<w:tc>
119    <w:tcPr>
120        <w:tcW w:w="6425" w:type="dxa"/>
121        <w:vMerge />
122    </w:tcPr>
123    <w:p>
124        <w:r>
125            <w:rPr></w:rPr>
126        </w:r>
127    </w:p>
128</w:tc>
129</w:document>"#;
130        let mut parser = EventReader::new(c.as_bytes());
131        let cell = TableCell::read(&mut parser, &[]).unwrap();
132        assert_eq!(
133            cell,
134            TableCell::new()
135                .add_paragraph(Paragraph::new().add_run(Run::new()))
136                .width(6425, WidthType::Dxa)
137                .vertical_merge(VMergeType::Continue),
138        );
139    }
140
141    #[test]
142    fn test_read_valign() {
143        let c = r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
144<w:tc>
145    <w:tcPr>
146        <w:tcW w:w="6425" w:type="dxa"/>
147        <w:vAlign w:val="bottom"/>
148    </w:tcPr>
149    <w:p>
150        <w:r>
151            <w:rPr></w:rPr>
152        </w:r>
153    </w:p>
154</w:tc>
155</w:document>"#;
156        let mut parser = EventReader::new(c.as_bytes());
157        let cell = TableCell::read(&mut parser, &[]).unwrap();
158        assert_eq!(
159            cell,
160            TableCell::new()
161                .add_paragraph(Paragraph::new().add_run(Run::new()))
162                .width(6425, WidthType::Dxa)
163                .vertical_align(VAlignType::Bottom),
164        );
165    }
166}