docx_rs/documents/elements/
line_spacing.rs

1use crate::documents::BuildXML;
2use crate::xml_builder::*;
3use std::io::Write;
4
5use crate::line_spacing_type::LineSpacingType;
6use serde::*;
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
9#[serde(rename_all = "camelCase")]
10pub struct LineSpacing {
11    #[serde(skip_serializing_if = "Option::is_none")]
12    line_rule: Option<LineSpacingType>,
13    #[serde(skip_serializing_if = "Option::is_none")]
14    before: Option<u32>,
15    #[serde(skip_serializing_if = "Option::is_none")]
16    after: Option<u32>,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    before_lines: Option<u32>,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    after_lines: Option<u32>,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    line: Option<i32>,
23}
24
25impl LineSpacing {
26    pub fn new() -> Self {
27        Self::default()
28    }
29
30    pub fn line_rule(mut self, t: LineSpacingType) -> Self {
31        self.line_rule = Some(t);
32        self
33    }
34
35    pub fn before(mut self, before: u32) -> Self {
36        self.before = Some(before);
37        self
38    }
39
40    pub fn after(mut self, after: u32) -> Self {
41        self.after = Some(after);
42        self
43    }
44
45    pub fn before_lines(mut self, before: u32) -> Self {
46        self.before_lines = Some(before);
47        self
48    }
49
50    pub fn after_lines(mut self, after: u32) -> Self {
51        self.after_lines = Some(after);
52        self
53    }
54
55    pub fn line(mut self, line: i32) -> Self {
56        self.line = Some(line);
57        self
58    }
59}
60
61impl BuildXML for LineSpacing {
62    fn build_to<W: Write>(
63        &self,
64        stream: xml::writer::EventWriter<W>,
65    ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
66        XMLBuilder::from(stream)
67            .line_spacing(
68                self.before,
69                self.after,
70                self.line,
71                self.before_lines,
72                self.after_lines,
73                self.line_rule,
74            )?
75            .into_inner()
76    }
77}
78
79#[cfg(test)]
80mod tests {
81
82    use super::*;
83    #[cfg(test)]
84    use pretty_assertions::assert_eq;
85    use std::str;
86
87    #[test]
88    fn test_spacing() {
89        let b = LineSpacing::new()
90            .line_rule(LineSpacingType::Auto)
91            .line(100)
92            .build();
93        assert_eq!(
94            str::from_utf8(&b).unwrap(),
95            r#"<w:spacing w:line="100" w:lineRule="auto" />"#
96        );
97    }
98
99    #[test]
100    fn test_spacing_after_lines() {
101        let b = LineSpacing::new()
102            .line_rule(LineSpacingType::Auto)
103            .after_lines(100)
104            .build();
105        assert_eq!(
106            str::from_utf8(&b).unwrap(),
107            r#"<w:spacing w:afterLines="100" w:lineRule="auto" />"#
108        );
109    }
110
111    #[test]
112    fn test_spacing_json() {
113        let s = LineSpacing {
114            line_rule: Some(LineSpacingType::Auto),
115            before: None,
116            after: None,
117            before_lines: None,
118            after_lines: None,
119            line: Some(100),
120        };
121        assert_eq!(
122            serde_json::to_string(&s).unwrap(),
123            r#"{"lineRule":"auto","line":100}"#
124        );
125    }
126}