docx_rs/documents/elements/
instr_tc.rs1use serde::Serialize;
2use std::io::Write;
3
4use crate::documents::*;
5use crate::escape::escape;
6use crate::xml_builder::XMLBuilder;
7
8#[derive(Serialize, Debug, Clone, PartialEq, Default)]
10#[serde(rename_all = "camelCase")]
11pub struct InstrTC {
12 pub text: String,
13 pub omits_page_number: bool,
15 pub level: Option<usize>,
16 pub item_type_identifier: Option<String>,
18}
19
20impl InstrTC {
21 pub fn new(text: impl Into<String>) -> Self {
22 Self {
23 text: escape(&text.into()),
24 ..Default::default()
25 }
26 }
27
28 pub fn omits_page_number(mut self) -> Self {
29 self.omits_page_number = true;
30 self
31 }
32
33 pub fn level(mut self, level: usize) -> Self {
34 self.level = Some(level);
35 self
36 }
37
38 pub fn item_type_identifier(mut self, t: impl Into<String>) -> Self {
39 self.item_type_identifier = Some(t.into());
40 self
41 }
42}
43
44impl BuildXML for InstrTC {
45 fn build_to<W: Write>(
46 &self,
47 stream: xml::writer::EventWriter<W>,
48 ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
49 let mut b = XMLBuilder::from(stream);
50 let raw = b.inner_mut()?;
51
52 write!(raw, "TC \"{}\"", self.text)?;
53
54 if let Some(ref t) = self.item_type_identifier {
55 write!(raw, " \\f {}", t)?;
56 }
57
58 if let Some(level) = self.level {
59 write!(raw, " \\l {}", level)?;
60 }
61
62 if self.omits_page_number {
63 write!(raw, " \\n")?;
64 }
65
66 b.into_inner()
67 }
68}
69
70fn parse_level(i: &str) -> Option<usize> {
71 let r = i.replace(""", "").replace('\"', "");
72 if let Ok(l) = usize::from_str(&r) {
73 return Some(l);
74 }
75 None
76}
77
78impl std::str::FromStr for InstrTC {
79 type Err = ();
80
81 fn from_str(instr: &str) -> Result<Self, Self::Err> {
82 let mut s = instr.split(' ');
83 let text = s.next();
84 let mut tc = InstrTC::new(text.unwrap_or_default());
85 loop {
86 if let Some(i) = s.next() {
87 match i {
88 "\\f" => {
89 if let Some(r) = s.next() {
90 let r = r.replace(""", "").replace('\"', "");
91 tc = tc.item_type_identifier(r);
92 }
93 }
94 "\\l" => {
95 if let Some(r) = s.next() {
96 if let Some(l) = parse_level(r) {
97 tc = tc.level(l);
98 }
99 }
100 }
101 "\\n" => tc = tc.omits_page_number(),
102 _ => {}
103 }
104 } else {
105 return Ok(tc);
106 }
107 }
108 }
109}