1use std::io::Read;
2use std::str::FromStr;
3
4use super::*;
5use crate::types::*;
6
7impl ElementReader for Table {
8 fn read<R: Read>(r: &mut EventReader<R>, _: &[OwnedAttribute]) -> Result<Self, ReaderError> {
9 let mut t = Table::without_borders(vec![]);
10 let mut grid_col: Vec<usize> = vec![];
11 loop {
12 let e = r.next();
13 match e {
14 Ok(XmlEvent::StartElement {
15 attributes, name, ..
16 }) => {
17 let e = XMLElement::from_str(&name.local_name).unwrap();
18
19 ignore::ignore_element(e.clone(), XMLElement::TablePropertyChange, r);
20 ignore::ignore_element(e.clone(), XMLElement::TableGridChange, r);
21
22 match e {
23 XMLElement::TableRow => {
24 t = t.add_row(TableRow::read(r, &attributes)?);
25 continue;
26 }
27 XMLElement::TableWidth => {
28 let (w, width_type) = read_width(&attributes)?;
29 t = t.width(w as usize, width_type);
30 continue;
31 }
32 XMLElement::TableProperty => {
33 if let Ok(p) = TableProperty::read(r, &attributes) {
34 t.property = p;
35 }
36 }
37 XMLElement::Justification => {
38 t = t.align(TableAlignmentType::from_str(&attributes[0].value)?);
39 }
40 XMLElement::TableIndent => {
41 let (w, _) = read_width(&attributes)?;
42 t = t.indent(w as i32);
43 continue;
44 }
45 XMLElement::TableBorders => {
46 if let Ok(borders) = TableBorders::read(r, &attributes) {
47 t = t.set_borders(borders);
48 }
49 }
50 XMLElement::TableStyle => {
51 if let Some(s) = read_val(&attributes) {
52 t = t.style(s);
53 }
54 }
55 XMLElement::TableCellMargin => {
56 if let Ok(margins) = TableCellMargins::read(r, &attributes) {
57 t = t.margins(margins)
58 }
59 }
60 XMLElement::GridCol => {
61 let (w, _) = read_width(&attributes)?;
62 grid_col.push(w as usize);
63 }
64 _ => {}
65 }
66 }
67 Ok(XmlEvent::EndElement { name, .. }) => {
68 let e = XMLElement::from_str(&name.local_name).unwrap();
69 if e == XMLElement::Table {
70 t = t.set_grid(grid_col);
71 return Ok(t);
72 }
73 }
74 Err(_) => return Err(ReaderError::XMLReadError),
75 _ => {}
76 }
77 }
78 }
79}
80
81#[cfg(test)]
82mod tests {
83
84 use super::*;
85 #[cfg(test)]
86 use pretty_assertions::assert_eq;
87
88 #[test]
89 fn test_read_table_with_width_prop() {
90 let c = r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
91<w:tbl>
92 <w:tblPr>
93 <w:tblW w:w="9638" w:type="dxa"/>
94 </w:tblPr>
95 <w:tblGrid>
96 <w:gridCol w:w="3212"/>
97 <w:gridCol w:w="3213"/>
98 <w:gridCol w:w="3213"/>
99 </w:tblGrid>
100</w:tbl>
101</w:document>"#;
102 let mut parser = EventReader::new(c.as_bytes());
103 let t = Table::read(&mut parser, &[]).unwrap();
104 assert_eq!(
105 t,
106 Table::without_borders(vec![])
107 .set_grid(vec![3212, 3213, 3213])
108 .width(9638, WidthType::Dxa)
109 );
110 }
111
112 #[test]
113 fn test_read_table_with_layout() {
114 let c = r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
115<w:tbl>
116 <w:tblPr>
117 <w:jc w:val="center"/>
118 <w:tblInd w:w="100" w:type="dxa"/>
119 </w:tblPr>
120</w:tbl>
121</w:document>"#;
122 let mut parser = EventReader::new(c.as_bytes());
123 let t = Table::read(&mut parser, &[]).unwrap();
124 assert_eq!(
125 t,
126 Table::without_borders(vec![])
127 .align(TableAlignmentType::Center)
128 .indent(100)
129 );
130 }
131}