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