docx_rs/documents/elements/
table_cell_borders.rs

1use serde::Serialize;
2use std::io::Write;
3
4use crate::documents::BuildXML;
5use crate::types::*;
6use crate::xml_builder::*;
7
8/*
9    Please see. L.4.3.2.18 Cell Border Properties
10
11    left – left border
12    right – right border
13    top – top border
14    bottom – bottom border
15    insideH – inner horizontal borders
16    insideV – inner vertical borders
17    tl2br – diagonal border from top left corner to bottom right corner
18    tr2bl – diagonal border from top right corner to bottom left corner
19*/
20#[derive(Serialize, Debug, Clone, PartialEq)]
21#[cfg_attr(feature = "wasm", derive(ts_rs::TS))]
22#[cfg_attr(feature = "wasm", ts(export))]
23#[serde(rename_all = "camelCase")]
24pub struct TableCellBorder {
25    pub border_type: BorderType,
26    pub size: usize,
27    pub color: String,
28    position: TableCellBorderPosition,
29    space: usize,
30}
31
32impl TableCellBorder {
33    pub fn new(position: TableCellBorderPosition) -> TableCellBorder {
34        TableCellBorder {
35            position,
36            border_type: BorderType::Single,
37            size: 2,
38            space: 0,
39            color: "000000".to_owned(),
40        }
41    }
42
43    pub fn color(mut self, color: impl Into<String>) -> TableCellBorder {
44        self.color = color.into();
45        self
46    }
47
48    pub fn size(mut self, size: usize) -> TableCellBorder {
49        self.size = size;
50        self
51    }
52
53    pub fn border_type(mut self, border_type: BorderType) -> TableCellBorder {
54        self.border_type = border_type;
55        self
56    }
57
58    pub fn get_size(&self) -> usize {
59        self.size
60    }
61
62    pub fn get_color(&self) -> String {
63        self.color.clone()
64    }
65
66    pub fn get_border_type(&self) -> BorderType {
67        self.border_type
68    }
69}
70
71impl BuildXML for TableCellBorder {
72    fn build_to<W: Write>(
73        &self,
74        stream: xml::writer::EventWriter<W>,
75    ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
76        let func = match self.position {
77            TableCellBorderPosition::Top => XMLBuilder::border_top,
78            TableCellBorderPosition::Left => XMLBuilder::border_left,
79            TableCellBorderPosition::Bottom => XMLBuilder::border_bottom,
80            TableCellBorderPosition::Right => XMLBuilder::border_right,
81            TableCellBorderPosition::InsideH => XMLBuilder::border_inside_h,
82            TableCellBorderPosition::InsideV => XMLBuilder::border_inside_v,
83            TableCellBorderPosition::Tr2bl => XMLBuilder::border_tr2bl,
84            TableCellBorderPosition::Tl2br => XMLBuilder::border_tl2br,
85        };
86        XMLBuilder::from(stream)
87            .apply(|b| func(b, self.border_type, self.size, self.space, &self.color))?
88            .into_inner()
89    }
90}
91
92#[derive(Serialize, Debug, Clone, PartialEq)]
93#[cfg_attr(feature = "wasm", derive(ts_rs::TS))]
94#[cfg_attr(feature = "wasm", ts(export))]
95#[serde(rename_all = "camelCase")]
96pub struct TableCellBorders {
97    top: Option<TableCellBorder>,
98    left: Option<TableCellBorder>,
99    bottom: Option<TableCellBorder>,
100    right: Option<TableCellBorder>,
101    inside_h: Option<TableCellBorder>,
102    inside_v: Option<TableCellBorder>,
103    tr2bl: Option<TableCellBorder>,
104    tl2br: Option<TableCellBorder>,
105}
106
107impl Default for TableCellBorders {
108    fn default() -> TableCellBorders {
109        TableCellBorders {
110            top: Some(TableCellBorder::new(TableCellBorderPosition::Top)),
111            left: Some(TableCellBorder::new(TableCellBorderPosition::Left)),
112            bottom: Some(TableCellBorder::new(TableCellBorderPosition::Bottom)),
113            right: Some(TableCellBorder::new(TableCellBorderPosition::Right)),
114            inside_h: Some(TableCellBorder::new(TableCellBorderPosition::InsideH)),
115            inside_v: Some(TableCellBorder::new(TableCellBorderPosition::InsideV)),
116            tr2bl: None,
117            tl2br: None,
118        }
119    }
120}
121
122impl TableCellBorders {
123    pub fn new() -> TableCellBorders {
124        Default::default()
125    }
126
127    pub fn with_empty() -> TableCellBorders {
128        TableCellBorders {
129            top: None,
130            left: None,
131            bottom: None,
132            right: None,
133            inside_h: None,
134            inside_v: None,
135            tr2bl: None,
136            tl2br: None,
137        }
138    }
139
140    pub fn set(mut self, border: TableCellBorder) -> Self {
141        match border.position {
142            TableCellBorderPosition::Top => self.top = Some(border),
143            TableCellBorderPosition::Left => self.left = Some(border),
144            TableCellBorderPosition::Bottom => self.bottom = Some(border),
145            TableCellBorderPosition::Right => self.right = Some(border),
146            TableCellBorderPosition::InsideH => self.inside_h = Some(border),
147            TableCellBorderPosition::InsideV => self.inside_v = Some(border),
148            TableCellBorderPosition::Tr2bl => self.tr2bl = Some(border),
149            TableCellBorderPosition::Tl2br => self.tl2br = Some(border),
150        };
151        self
152    }
153
154    pub fn clear(mut self, position: TableCellBorderPosition) -> Self {
155        let nil = TableCellBorder::new(position.clone()).border_type(BorderType::Nil);
156        match position {
157            TableCellBorderPosition::Top => self.top = Some(nil),
158            TableCellBorderPosition::Left => self.left = Some(nil),
159            TableCellBorderPosition::Bottom => self.bottom = Some(nil),
160            TableCellBorderPosition::Right => self.right = Some(nil),
161            TableCellBorderPosition::InsideH => self.inside_h = Some(nil),
162            TableCellBorderPosition::InsideV => self.inside_v = Some(nil),
163            TableCellBorderPosition::Tr2bl => self.tr2bl = Some(nil),
164            TableCellBorderPosition::Tl2br => self.tl2br = Some(nil),
165        };
166        self
167    }
168
169    pub fn clear_all(mut self) -> Self {
170        self.top =
171            Some(TableCellBorder::new(TableCellBorderPosition::Top).border_type(BorderType::Nil));
172        self.left =
173            Some(TableCellBorder::new(TableCellBorderPosition::Left).border_type(BorderType::Nil));
174        self.bottom = Some(
175            TableCellBorder::new(TableCellBorderPosition::Bottom).border_type(BorderType::Nil),
176        );
177        self.right =
178            Some(TableCellBorder::new(TableCellBorderPosition::Right).border_type(BorderType::Nil));
179        self.inside_h = Some(
180            TableCellBorder::new(TableCellBorderPosition::InsideH).border_type(BorderType::Nil),
181        );
182        self.inside_v = Some(
183            TableCellBorder::new(TableCellBorderPosition::InsideV).border_type(BorderType::Nil),
184        );
185        self.tl2br =
186            Some(TableCellBorder::new(TableCellBorderPosition::Tl2br).border_type(BorderType::Nil));
187        self.tr2bl =
188            Some(TableCellBorder::new(TableCellBorderPosition::Tr2bl).border_type(BorderType::Nil));
189        self
190    }
191}
192
193impl BuildXML for TableCellBorders {
194    fn build_to<W: Write>(
195        &self,
196        stream: xml::writer::EventWriter<W>,
197    ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
198        XMLBuilder::from(stream)
199            .open_table_cell_borders()?
200            .add_optional_child(&self.top)?
201            .add_optional_child(&self.left)?
202            .add_optional_child(&self.bottom)?
203            .add_optional_child(&self.right)?
204            .add_optional_child(&self.inside_h)?
205            .add_optional_child(&self.inside_v)?
206            .add_optional_child(&self.tl2br)?
207            .add_optional_child(&self.tr2bl)?
208            .close()?
209            .into_inner()
210    }
211}