docx_rs/documents/elements/
cell_margins.rs

1use serde::Serialize;
2use std::io::Write;
3
4use crate::documents::BuildXML;
5use crate::types::*;
6use crate::xml_builder::*;
7
8#[derive(Debug, Clone, PartialEq, Serialize)]
9#[serde(rename_all = "camelCase")]
10pub struct CellMargin {
11    pub val: usize,
12    pub width_type: WidthType,
13}
14
15impl CellMargin {
16    pub fn new(val: usize, t: WidthType) -> Self {
17        Self { val, width_type: t }
18    }
19}
20
21impl Default for CellMargin {
22    fn default() -> CellMargin {
23        CellMargin {
24            val: 55,
25            width_type: WidthType::Dxa,
26        }
27    }
28}
29
30#[derive(Debug, Clone, PartialEq, Serialize, Default)]
31#[serde(rename_all = "camelCase")]
32pub struct CellMargins {
33    #[serde(skip_serializing_if = "Option::is_none")]
34    top: Option<CellMargin>,
35    #[serde(skip_serializing_if = "Option::is_none")]
36    left: Option<CellMargin>,
37    #[serde(skip_serializing_if = "Option::is_none")]
38    bottom: Option<CellMargin>,
39    #[serde(skip_serializing_if = "Option::is_none")]
40    right: Option<CellMargin>,
41}
42
43impl CellMargins {
44    pub fn new() -> CellMargins {
45        Default::default()
46    }
47
48    pub fn margin_top(mut self, v: usize, t: WidthType) -> Self {
49        self.top = Some(CellMargin::new(v, t));
50        self
51    }
52
53    pub fn margin_right(mut self, v: usize, t: WidthType) -> Self {
54        self.right = Some(CellMargin::new(v, t));
55        self
56    }
57
58    pub fn margin_left(mut self, v: usize, t: WidthType) -> Self {
59        self.left = Some(CellMargin::new(v, t));
60        self
61    }
62
63    pub fn margin_bottom(mut self, v: usize, t: WidthType) -> Self {
64        self.bottom = Some(CellMargin::new(v, t));
65        self
66    }
67}
68
69impl BuildXML for CellMargins {
70    fn build_to<W: Write>(
71        &self,
72        stream: xml::writer::EventWriter<W>,
73    ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
74        XMLBuilder::from(stream)
75            .open_cell_margins()?
76            .apply_opt(self.top.as_ref(), |top, b| {
77                b.margin_top(top.val as i32, top.width_type)
78            })?
79            .apply_opt(self.left.as_ref(), |left, b| {
80                b.margin_left(left.val as i32, left.width_type)
81            })?
82            .apply_opt(self.bottom.as_ref(), |bottom, b| {
83                b.margin_bottom(bottom.val as i32, bottom.width_type)
84            })?
85            .apply_opt(self.right.as_ref(), |right, b| {
86                b.margin_right(right.val as i32, right.width_type)
87            })?
88            .close()?
89            .into_inner()
90    }
91}
92
93#[cfg(test)]
94mod tests {
95
96    use super::*;
97    #[cfg(test)]
98    use pretty_assertions::assert_eq;
99    use std::str;
100
101    #[test]
102    fn test_cell_margin() {
103        let b = CellMargins::new().margin_top(10, WidthType::Dxa).build();
104        assert_eq!(
105            str::from_utf8(&b).unwrap(),
106            r#"<w:tcMar><w:top w:w="10" w:type="dxa" /></w:tcMar>"#
107        );
108    }
109}