docx_rs/documents/elements/
run_fonts.rs

1use serde::{Deserialize, Serialize};
2use std::io::Write;
3
4use crate::documents::BuildXML;
5use crate::escape::escape;
6use crate::xml_builder::*;
7
8/*
9  17.3.2.26 rFonts (Run Fonts)
10  This element specifies the fonts which shall be used to display the text contents of this run.
11  Within a single run, there can be up to four types of font slot which shall each be allowed to use a unique font:
12  - ASCII (i.e., the first 128 Unicode code points)
13  - High ANSI
14  - Complex Script
15*/
16#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
17#[serde(rename_all = "camelCase")]
18pub struct RunFonts {
19    #[serde(skip_serializing_if = "Option::is_none")]
20    ascii: Option<String>,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    hi_ansi: Option<String>,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    east_asia: Option<String>,
25    #[serde(skip_serializing_if = "Option::is_none")]
26    cs: Option<String>,
27    #[serde(skip_serializing_if = "Option::is_none")]
28    ascii_theme: Option<String>,
29    #[serde(skip_serializing_if = "Option::is_none")]
30    hi_ansi_theme: Option<String>,
31    #[serde(skip_serializing_if = "Option::is_none")]
32    east_asia_theme: Option<String>,
33    #[serde(skip_serializing_if = "Option::is_none")]
34    cs_theme: Option<String>,
35    #[serde(skip_serializing_if = "Option::is_none")]
36    hint: Option<String>,
37}
38
39impl RunFonts {
40    pub fn new() -> RunFonts {
41        Default::default()
42    }
43
44    pub fn ascii(mut self, f: impl Into<String>) -> Self {
45        let s = f.into();
46        self.ascii = Some(escape(&s));
47        self
48    }
49
50    pub fn hi_ansi(mut self, f: impl Into<String>) -> Self {
51        let s = f.into();
52        self.hi_ansi = Some(escape(&s));
53        self
54    }
55
56    pub fn east_asia(mut self, f: impl Into<String>) -> Self {
57        let s = f.into();
58        self.east_asia = Some(escape(&s));
59        self
60    }
61
62    pub fn cs(mut self, f: impl Into<String>) -> Self {
63        let s = f.into();
64        self.cs = Some(escape(&s));
65        self
66    }
67
68    pub fn ascii_theme(mut self, f: impl Into<String>) -> Self {
69        let s = f.into();
70        self.ascii_theme = Some(escape(&s));
71        self
72    }
73
74    pub fn hi_ansi_theme(mut self, f: impl Into<String>) -> Self {
75        let s = f.into();
76        self.hi_ansi_theme = Some(escape(&s));
77        self
78    }
79
80    pub fn east_asia_theme(mut self, f: impl Into<String>) -> Self {
81        let s = f.into();
82        self.east_asia_theme = Some(escape(&s));
83        self
84    }
85
86    pub fn cs_theme(mut self, f: impl Into<String>) -> Self {
87        let s = f.into();
88        self.cs_theme = Some(escape(&s));
89        self
90    }
91
92    pub fn hint(mut self, f: impl Into<String>) -> Self {
93        let s = f.into();
94        self.hint = Some(escape(&s));
95        self
96    }
97}
98
99impl BuildXML for RunFonts {
100    fn build_to<W: Write>(
101        &self,
102        stream: xml::writer::EventWriter<W>,
103    ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
104        XMLBuilder::from(stream)
105            .run_fonts(
106                self.ascii.as_ref(),
107                self.hi_ansi.as_ref(),
108                self.cs.as_ref(),
109                self.east_asia.as_ref(),
110                self.ascii_theme.as_ref(),
111                self.hi_ansi_theme.as_ref(),
112                self.cs_theme.as_ref(),
113                self.east_asia_theme.as_ref(),
114                self.hint.as_ref(),
115            )?
116            .into_inner()
117    }
118}
119
120#[cfg(test)]
121mod tests {
122
123    use super::*;
124    #[cfg(test)]
125    use pretty_assertions::assert_eq;
126    use std::str;
127
128    #[test]
129    fn test_run_fonts_east_asia_build() {
130        let c = RunFonts::new().east_asia("Hiragino");
131        let b = c.build();
132        assert_eq!(
133            str::from_utf8(&b).unwrap(),
134            r#"<w:rFonts w:eastAsia="Hiragino" />"#
135        );
136    }
137
138    #[test]
139    fn test_run_fonts_ascii_build() {
140        let c = RunFonts::new().ascii("Arial");
141        let b = c.build();
142        assert_eq!(
143            str::from_utf8(&b).unwrap(),
144            r#"<w:rFonts w:ascii="Arial" />"#
145        );
146    }
147
148    #[test]
149    fn test_run_fonts_hi_ansi_build() {
150        let c = RunFonts::new().hi_ansi("Arial");
151        let b = c.build();
152        assert_eq!(
153            str::from_utf8(&b).unwrap(),
154            r#"<w:rFonts w:hAnsi="Arial" />"#
155        );
156    }
157
158    #[test]
159    fn test_run_fonts_cs_build() {
160        let c = RunFonts::new().cs("Arial");
161        let b = c.build();
162        assert_eq!(str::from_utf8(&b).unwrap(), r#"<w:rFonts w:cs="Arial" />"#);
163    }
164
165    #[test]
166    fn test_run_fonts_with_escape() {
167        let c = RunFonts::new().east_asia(r#""Calibri",sans-serif"#);
168        let b = c.build();
169        assert_eq!(
170            str::from_utf8(&b).unwrap(),
171            r#"<w:rFonts w:eastAsia="&quot;Calibri&quot;,sans-serif" />"#,
172        );
173    }
174}