docx_rs/documents/elements/
frame_property.rs

1use serde::Serialize;
2use std::io::Write;
3
4use crate::documents::BuildXML;
5use crate::xml_builder::*;
6
7// https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.wordprocessing.frameproperties?view=openxml-3.0.1
8#[derive(Debug, Clone, PartialEq, Serialize, Default)]
9#[serde(rename_all = "camelCase")]
10#[cfg_attr(feature = "wasm", derive(ts_rs::TS))]
11#[cfg_attr(feature = "wasm", ts(export))]
12pub struct FrameProperty {
13    /// Frame Height
14    /// Represents the following attribute in the schema: w:h
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub h: Option<u32>,
17    /// Frame Height Type
18    /// Represents the following attribute in the schema: w:hRule
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub h_rule: Option<String>,
21    /// Frame Horizontal Positioning Base
22    /// Represents the following attribute in the schema: w:hAnchor
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub h_anchor: Option<String>,
25    /// Horizontal Frame Padding
26    /// Represents the following attribute in the schema: w:hSpace
27    #[serde(skip_serializing_if = "Option::is_none")]
28    pub h_space: Option<i32>,
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub v_anchor: Option<String>,
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub v_space: Option<i32>,
33    #[serde(skip_serializing_if = "Option::is_none")]
34    pub w: Option<u32>,
35    /// Text Wrapping Around Frame
36    /// Represents the following attribute in the schema: w:wrap
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub wrap: Option<String>,
39    /// Absolute Horizontal Position
40    /// Represents the following attribute in the schema: w:x
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub x: Option<i32>,
43    /// Relative Horizontal Position
44    /// Represents the following attribute in the schema: w:xAlign
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub x_align: Option<String>,
47    /// Absolute Vertical Position
48    /// Represents the following attribute in the schema: w:y
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub y: Option<i32>,
51    /// Relative Vertical Position
52    /// Represents the following attribute in the schema: w:yAlign
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub y_align: Option<String>,
55}
56
57impl FrameProperty {
58    pub fn new() -> FrameProperty {
59        Default::default()
60    }
61
62    pub fn wrap(mut self, wrap: impl Into<String>) -> Self {
63        self.wrap = Some(wrap.into());
64        self
65    }
66
67    pub fn v_anchor(mut self, anchor: impl Into<String>) -> Self {
68        self.v_anchor = Some(anchor.into());
69        self
70    }
71
72    pub fn h_anchor(mut self, anchor: impl Into<String>) -> Self {
73        self.h_anchor = Some(anchor.into());
74        self
75    }
76
77    pub fn h_rule(mut self, r: impl Into<String>) -> Self {
78        self.h_rule = Some(r.into());
79        self
80    }
81
82    pub fn x_align(mut self, align: impl Into<String>) -> Self {
83        self.x_align = Some(align.into());
84        self
85    }
86
87    pub fn y_align(mut self, align: impl Into<String>) -> Self {
88        self.y_align = Some(align.into());
89        self
90    }
91
92    pub fn h_space(mut self, x: i32) -> Self {
93        self.h_space = Some(x);
94        self
95    }
96
97    pub fn v_space(mut self, x: i32) -> Self {
98        self.v_space = Some(x);
99        self
100    }
101
102    pub fn x(mut self, x: i32) -> Self {
103        self.x = Some(x);
104        self
105    }
106
107    pub fn y(mut self, y: i32) -> Self {
108        self.y = Some(y);
109        self
110    }
111
112    pub fn width(mut self, n: u32) -> Self {
113        self.w = Some(n);
114        self
115    }
116
117    pub fn height(mut self, n: u32) -> Self {
118        self.h = Some(n);
119        self
120    }
121}
122
123impl BuildXML for FrameProperty {
124    fn build_to<W: Write>(
125        &self,
126        stream: xml::writer::EventWriter<W>,
127    ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
128        XMLBuilder::from(stream).frame_property(self)?.into_inner()
129    }
130}
131
132#[cfg(test)]
133mod tests {
134
135    use super::*;
136    #[cfg(test)]
137    use pretty_assertions::assert_eq;
138    use std::str;
139
140    #[test]
141    fn test_q_format() {
142        let c = FrameProperty::new().wrap("none");
143        let b = c.build();
144        assert_eq!(
145            str::from_utf8(&b).unwrap(),
146            r#"<w:framePr w:wrap="none" />"#
147        );
148    }
149}