docx_rs/documents/elements/
instr_text.rs

1use serde::ser::{SerializeStruct, Serializer};
2use serde::Serialize;
3use std::io::Write;
4
5use crate::documents::*;
6use crate::xml_builder::*;
7
8#[derive(Debug, Clone, PartialEq)]
9pub enum InstrText {
10    TOC(InstrToC),
11    TC(InstrTC),
12    PAGE(InstrPAGE),
13    NUMPAGES(InstrNUMPAGES),
14    PAGEREF(InstrPAGEREF),
15    HYPERLINK(InstrHyperlink),
16    Unsupported(String),
17}
18
19impl BuildXML for Box<InstrText> {
20    fn build_to<W: Write>(
21        &self,
22        stream: xml::writer::EventWriter<W>,
23    ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
24        XMLBuilder::from(stream)
25            .open_instr_text()?
26            .apply(|b| match self.as_ref() {
27                InstrText::TOC(toc) => b.add_child(toc),
28                InstrText::TC(tc) => b.add_child(tc),
29                InstrText::PAGEREF(page_ref) => b.add_child(page_ref),
30                InstrText::PAGE(page) => b.add_child(page),
31                InstrText::NUMPAGES(page) => b.add_child(page),
32                InstrText::HYPERLINK(_link) => todo!(),
33                InstrText::Unsupported(s) => b.plain_text(s),
34            })?
35            .close()?
36            .into_inner()
37    }
38}
39
40impl Serialize for InstrText {
41    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
42    where
43        S: Serializer,
44    {
45        match *self {
46            InstrText::TOC(ref s) => {
47                let mut t = serializer.serialize_struct("TOC", 2)?;
48                t.serialize_field("type", "toc")?;
49                t.serialize_field("data", s)?;
50                t.end()
51            }
52            InstrText::TC(ref s) => {
53                let mut t = serializer.serialize_struct("TC", 2)?;
54                t.serialize_field("type", "tc")?;
55                t.serialize_field("data", s)?;
56                t.end()
57            }
58            InstrText::PAGEREF(ref s) => {
59                let mut t = serializer.serialize_struct("PAGEREF", 2)?;
60                t.serialize_field("type", "pageref")?;
61                t.serialize_field("data", s)?;
62                t.end()
63            }
64            InstrText::PAGE(ref s) => {
65                let mut t = serializer.serialize_struct("PAGE", 2)?;
66                t.serialize_field("type", "page")?;
67                t.serialize_field("data", s)?;
68                t.end()
69            }
70            InstrText::NUMPAGES(ref s) => {
71                let mut t = serializer.serialize_struct("NUMPAGES", 2)?;
72                t.serialize_field("type", "numPages")?;
73                t.serialize_field("data", s)?;
74                t.end()
75            }
76            InstrText::HYPERLINK(ref s) => {
77                let mut t = serializer.serialize_struct("HYPERLINK", 2)?;
78                t.serialize_field("type", "hyperlink")?;
79                t.serialize_field("data", s)?;
80                t.end()
81            }
82            InstrText::Unsupported(ref s) => {
83                let mut t = serializer.serialize_struct("Unsupported", 2)?;
84                t.serialize_field("type", "unsupported")?;
85                t.serialize_field("data", s)?;
86                t.end()
87            }
88        }
89    }
90}
91
92#[allow(unused_allocation)]
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_toc_instr() {
103        #[allow(unused_allocation)]
104        let b = Box::new(InstrText::TOC(InstrToC::new().heading_styles_range(1, 3))).build();
105        assert_eq!(
106            str::from_utf8(&b).unwrap(),
107            r#"<w:instrText>TOC \o &quot;1-3&quot;</w:instrText>"#
108        );
109    }
110
111    #[test]
112    fn test_pageref_instr() {
113        #[allow(unused_allocation)]
114        let b = Box::new(InstrText::PAGEREF(
115            InstrPAGEREF::new("_Toc90425847").hyperlink(),
116        ))
117        .build();
118        assert_eq!(
119            str::from_utf8(&b).unwrap(),
120            r#"<w:instrText>PAGEREF _Toc90425847 \h</w:instrText>"#
121        );
122    }
123}