Skip to main content

rdocx_oxml/
shared.rs

1//! Shared simple types and enums used across OOXML elements.
2
3use crate::error::{OxmlError, Result};
4
5/// `ST_Jc` — Paragraph justification.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum ST_Jc {
8    Start,
9    End,
10    Center,
11    Both,
12    Distribute,
13    Left,
14    Right,
15}
16
17impl ST_Jc {
18    pub fn from_str(s: &str) -> Result<Self> {
19        match s {
20            "start" | "left" => Ok(ST_Jc::Left),
21            "end" | "right" => Ok(ST_Jc::Right),
22            "center" => Ok(ST_Jc::Center),
23            "both" | "justify" => Ok(ST_Jc::Both),
24            "distribute" => Ok(ST_Jc::Distribute),
25            _ => Err(OxmlError::InvalidValue(format!("invalid ST_Jc: {s}"))),
26        }
27    }
28
29    pub fn to_str(self) -> &'static str {
30        match self {
31            ST_Jc::Start | ST_Jc::Left => "left",
32            ST_Jc::End | ST_Jc::Right => "right",
33            ST_Jc::Center => "center",
34            ST_Jc::Both => "both",
35            ST_Jc::Distribute => "distribute",
36        }
37    }
38}
39
40/// `ST_OnOff` — Boolean toggle, can be represented as "true"/"false", "1"/"0", or attribute absence.
41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub enum ST_OnOff {
43    On,
44    Off,
45}
46
47impl ST_OnOff {
48    pub fn from_str_or_default(s: Option<&str>) -> Self {
49        match s {
50            // If the attribute is absent or empty, the element presence means "on"
51            None | Some("") | Some("true") | Some("1") | Some("on") => ST_OnOff::On,
52            Some("false") | Some("0") | Some("off") => ST_OnOff::Off,
53            Some(_) => ST_OnOff::Off,
54        }
55    }
56
57    pub fn is_on(self) -> bool {
58        self == ST_OnOff::On
59    }
60
61    pub fn to_str(self) -> &'static str {
62        match self {
63            ST_OnOff::On => "true",
64            ST_OnOff::Off => "false",
65        }
66    }
67}
68
69/// `ST_UnderlineType` — Underline styles.
70#[derive(Debug, Clone, Copy, PartialEq, Eq)]
71pub enum ST_Underline {
72    None,
73    Single,
74    Words,
75    Double,
76    Thick,
77    Dotted,
78    Dash,
79    DotDash,
80    DotDotDash,
81    Wave,
82}
83
84impl ST_Underline {
85    pub fn from_str(s: &str) -> Result<Self> {
86        match s {
87            "none" => Ok(ST_Underline::None),
88            "single" => Ok(ST_Underline::Single),
89            "words" => Ok(ST_Underline::Words),
90            "double" => Ok(ST_Underline::Double),
91            "thick" => Ok(ST_Underline::Thick),
92            "dotted" => Ok(ST_Underline::Dotted),
93            "dash" => Ok(ST_Underline::Dash),
94            "dotDash" => Ok(ST_Underline::DotDash),
95            "dotDotDash" => Ok(ST_Underline::DotDotDash),
96            "wave" => Ok(ST_Underline::Wave),
97            _ => Err(OxmlError::InvalidValue(format!(
98                "invalid ST_Underline: {s}"
99            ))),
100        }
101    }
102
103    pub fn to_str(self) -> &'static str {
104        match self {
105            ST_Underline::None => "none",
106            ST_Underline::Single => "single",
107            ST_Underline::Words => "words",
108            ST_Underline::Double => "double",
109            ST_Underline::Thick => "thick",
110            ST_Underline::Dotted => "dotted",
111            ST_Underline::Dash => "dash",
112            ST_Underline::DotDash => "dotDash",
113            ST_Underline::DotDotDash => "dotDotDash",
114            ST_Underline::Wave => "wave",
115        }
116    }
117}
118
119/// `ST_Border` — Border styles.
120#[derive(Debug, Clone, Copy, PartialEq, Eq)]
121pub enum ST_Border {
122    None,
123    Single,
124    Thick,
125    Double,
126    Dotted,
127    Dashed,
128    DotDash,
129    DotDotDash,
130    Triple,
131    ThinThickSmallGap,
132    ThickThinSmallGap,
133    ThinThickMediumGap,
134    ThickThinMediumGap,
135    ThinThickLargeGap,
136    ThickThinLargeGap,
137    Wave,
138    DoubleWave,
139    ThreeDEmboss,
140    ThreeDEngrave,
141    Outset,
142    Inset,
143}
144
145impl ST_Border {
146    pub fn from_str(s: &str) -> Result<Self> {
147        match s {
148            "none" | "nil" => Ok(Self::None),
149            "single" => Ok(Self::Single),
150            "thick" => Ok(Self::Thick),
151            "double" => Ok(Self::Double),
152            "dotted" => Ok(Self::Dotted),
153            "dashed" => Ok(Self::Dashed),
154            "dotDash" => Ok(Self::DotDash),
155            "dotDotDash" => Ok(Self::DotDotDash),
156            "triple" => Ok(Self::Triple),
157            "thinThickSmallGap" => Ok(Self::ThinThickSmallGap),
158            "thickThinSmallGap" => Ok(Self::ThickThinSmallGap),
159            "thinThickMediumGap" => Ok(Self::ThinThickMediumGap),
160            "thickThinMediumGap" => Ok(Self::ThickThinMediumGap),
161            "thinThickLargeGap" => Ok(Self::ThinThickLargeGap),
162            "thickThinLargeGap" => Ok(Self::ThickThinLargeGap),
163            "wave" => Ok(Self::Wave),
164            "doubleWave" => Ok(Self::DoubleWave),
165            "threeDEmboss" => Ok(Self::ThreeDEmboss),
166            "threeDEngrave" => Ok(Self::ThreeDEngrave),
167            "outset" => Ok(Self::Outset),
168            "inset" => Ok(Self::Inset),
169            _ => Err(OxmlError::InvalidValue(format!("invalid ST_Border: {s}"))),
170        }
171    }
172
173    pub fn to_str(self) -> &'static str {
174        match self {
175            Self::None => "none",
176            Self::Single => "single",
177            Self::Thick => "thick",
178            Self::Double => "double",
179            Self::Dotted => "dotted",
180            Self::Dashed => "dashed",
181            Self::DotDash => "dotDash",
182            Self::DotDotDash => "dotDotDash",
183            Self::Triple => "triple",
184            Self::ThinThickSmallGap => "thinThickSmallGap",
185            Self::ThickThinSmallGap => "thickThinSmallGap",
186            Self::ThinThickMediumGap => "thinThickMediumGap",
187            Self::ThickThinMediumGap => "thickThinMediumGap",
188            Self::ThinThickLargeGap => "thinThickLargeGap",
189            Self::ThickThinLargeGap => "thickThinLargeGap",
190            Self::Wave => "wave",
191            Self::DoubleWave => "doubleWave",
192            Self::ThreeDEmboss => "threeDEmboss",
193            Self::ThreeDEngrave => "threeDEngrave",
194            Self::Outset => "outset",
195            Self::Inset => "inset",
196        }
197    }
198}
199
200/// `ST_TabJc` — Tab stop alignment type.
201#[derive(Debug, Clone, Copy, PartialEq, Eq)]
202pub enum ST_TabJc {
203    Left,
204    Center,
205    Right,
206    Decimal,
207    Bar,
208    Clear,
209    Num,
210}
211
212impl ST_TabJc {
213    pub fn from_str(s: &str) -> Result<Self> {
214        match s {
215            "left" | "start" => Ok(Self::Left),
216            "center" => Ok(Self::Center),
217            "right" | "end" => Ok(Self::Right),
218            "decimal" => Ok(Self::Decimal),
219            "bar" => Ok(Self::Bar),
220            "clear" => Ok(Self::Clear),
221            "num" => Ok(Self::Num),
222            _ => Err(OxmlError::InvalidValue(format!("invalid ST_TabJc: {s}"))),
223        }
224    }
225
226    pub fn to_str(self) -> &'static str {
227        match self {
228            Self::Left => "left",
229            Self::Center => "center",
230            Self::Right => "right",
231            Self::Decimal => "decimal",
232            Self::Bar => "bar",
233            Self::Clear => "clear",
234            Self::Num => "num",
235        }
236    }
237}
238
239/// `ST_TabTlc` — Tab leader character.
240#[derive(Debug, Clone, Copy, PartialEq, Eq)]
241pub enum ST_TabLeader {
242    None,
243    Dot,
244    Hyphen,
245    Underscore,
246    Heavy,
247    MiddleDot,
248}
249
250impl ST_TabLeader {
251    pub fn from_str(s: &str) -> Result<Self> {
252        match s {
253            "none" => Ok(Self::None),
254            "dot" => Ok(Self::Dot),
255            "hyphen" => Ok(Self::Hyphen),
256            "underscore" => Ok(Self::Underscore),
257            "heavy" => Ok(Self::Heavy),
258            "middleDot" => Ok(Self::MiddleDot),
259            _ => Err(OxmlError::InvalidValue(format!(
260                "invalid ST_TabLeader: {s}"
261            ))),
262        }
263    }
264
265    pub fn to_str(self) -> &'static str {
266        match self {
267            Self::None => "none",
268            Self::Dot => "dot",
269            Self::Hyphen => "hyphen",
270            Self::Underscore => "underscore",
271            Self::Heavy => "heavy",
272            Self::MiddleDot => "middleDot",
273        }
274    }
275}
276
277/// `ST_SectionType` — Section break type.
278#[derive(Debug, Clone, Copy, PartialEq, Eq)]
279pub enum ST_SectionType {
280    NextPage,
281    Continuous,
282    EvenPage,
283    OddPage,
284    NextColumn,
285}
286
287impl ST_SectionType {
288    pub fn from_str(s: &str) -> Result<Self> {
289        match s {
290            "nextPage" => Ok(Self::NextPage),
291            "continuous" => Ok(Self::Continuous),
292            "evenPage" => Ok(Self::EvenPage),
293            "oddPage" => Ok(Self::OddPage),
294            "nextColumn" => Ok(Self::NextColumn),
295            _ => Err(OxmlError::InvalidValue(format!(
296                "invalid ST_SectionType: {s}"
297            ))),
298        }
299    }
300
301    pub fn to_str(self) -> &'static str {
302        match self {
303            Self::NextPage => "nextPage",
304            Self::Continuous => "continuous",
305            Self::EvenPage => "evenPage",
306            Self::OddPage => "oddPage",
307            Self::NextColumn => "nextColumn",
308        }
309    }
310}
311
312/// `ST_PageOrientation` — Page orientation.
313#[derive(Debug, Clone, Copy, PartialEq, Eq)]
314pub enum ST_PageOrientation {
315    Portrait,
316    Landscape,
317}
318
319impl ST_PageOrientation {
320    pub fn from_str(s: &str) -> Result<Self> {
321        match s {
322            "portrait" => Ok(Self::Portrait),
323            "landscape" => Ok(Self::Landscape),
324            _ => Err(OxmlError::InvalidValue(format!(
325                "invalid ST_PageOrientation: {s}"
326            ))),
327        }
328    }
329
330    pub fn to_str(self) -> &'static str {
331        match self {
332            Self::Portrait => "portrait",
333            Self::Landscape => "landscape",
334        }
335    }
336}
337
338/// `ST_HighlightColor` — Highlight colors.
339#[derive(Debug, Clone, Copy, PartialEq, Eq)]
340pub enum ST_HighlightColor {
341    Black,
342    Blue,
343    Cyan,
344    DarkBlue,
345    DarkCyan,
346    DarkGray,
347    DarkGreen,
348    DarkMagenta,
349    DarkRed,
350    DarkYellow,
351    Green,
352    LightGray,
353    Magenta,
354    None,
355    Red,
356    White,
357    Yellow,
358}
359
360impl ST_HighlightColor {
361    pub fn from_str(s: &str) -> Result<Self> {
362        match s {
363            "black" => Ok(Self::Black),
364            "blue" => Ok(Self::Blue),
365            "cyan" => Ok(Self::Cyan),
366            "darkBlue" => Ok(Self::DarkBlue),
367            "darkCyan" => Ok(Self::DarkCyan),
368            "darkGray" => Ok(Self::DarkGray),
369            "darkGreen" => Ok(Self::DarkGreen),
370            "darkMagenta" => Ok(Self::DarkMagenta),
371            "darkRed" => Ok(Self::DarkRed),
372            "darkYellow" => Ok(Self::DarkYellow),
373            "green" => Ok(Self::Green),
374            "lightGray" => Ok(Self::LightGray),
375            "magenta" => Ok(Self::Magenta),
376            "none" => Ok(Self::None),
377            "red" => Ok(Self::Red),
378            "white" => Ok(Self::White),
379            "yellow" => Ok(Self::Yellow),
380            _ => Err(OxmlError::InvalidValue(format!(
381                "invalid ST_HighlightColor: {s}"
382            ))),
383        }
384    }
385
386    pub fn to_str(self) -> &'static str {
387        match self {
388            Self::Black => "black",
389            Self::Blue => "blue",
390            Self::Cyan => "cyan",
391            Self::DarkBlue => "darkBlue",
392            Self::DarkCyan => "darkCyan",
393            Self::DarkGray => "darkGray",
394            Self::DarkGreen => "darkGreen",
395            Self::DarkMagenta => "darkMagenta",
396            Self::DarkRed => "darkRed",
397            Self::DarkYellow => "darkYellow",
398            Self::Green => "green",
399            Self::LightGray => "lightGray",
400            Self::Magenta => "magenta",
401            Self::None => "none",
402            Self::Red => "red",
403            Self::White => "white",
404            Self::Yellow => "yellow",
405        }
406    }
407}