Skip to main content

hwpforge_foundation/enums/
tab.rs

1//! Tab-stop enums: tab alignment and tab leader characters.
2
3use crate::error::FoundationError;
4use serde::{Deserialize, Serialize};
5use std::fmt;
6
7// ---------------------------------------------------------------------------
8// TabAlign
9// ---------------------------------------------------------------------------
10
11/// Tab stop alignment.
12///
13/// Maps to HWPX `<hh:tabItem type="...">`.
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
15#[non_exhaustive]
16#[repr(u8)]
17pub enum TabAlign {
18    /// Left-aligned tab.
19    #[default]
20    Left = 0,
21    /// Right-aligned tab.
22    Right = 1,
23    /// Center-aligned tab.
24    Center = 2,
25    /// Decimal-aligned tab.
26    Decimal = 3,
27}
28
29impl TabAlign {
30    /// Converts to the HWPX XML attribute string.
31    pub fn to_hwpx_str(self) -> &'static str {
32        match self {
33            Self::Left => "LEFT",
34            Self::Right => "RIGHT",
35            Self::Center => "CENTER",
36            Self::Decimal => "DECIMAL",
37        }
38    }
39
40    /// Parses a HWPX XML attribute string.
41    pub fn from_hwpx_str(s: &str) -> Self {
42        match s {
43            "RIGHT" => Self::Right,
44            "CENTER" => Self::Center,
45            "DECIMAL" => Self::Decimal,
46            _ => Self::Left,
47        }
48    }
49}
50
51impl fmt::Display for TabAlign {
52    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53        match self {
54            Self::Left => f.write_str("Left"),
55            Self::Right => f.write_str("Right"),
56            Self::Center => f.write_str("Center"),
57            Self::Decimal => f.write_str("Decimal"),
58        }
59    }
60}
61
62impl std::str::FromStr for TabAlign {
63    type Err = FoundationError;
64
65    fn from_str(s: &str) -> Result<Self, Self::Err> {
66        match s {
67            "Left" | "LEFT" | "left" => Ok(Self::Left),
68            "Right" | "RIGHT" | "right" => Ok(Self::Right),
69            "Center" | "CENTER" | "center" => Ok(Self::Center),
70            "Decimal" | "DECIMAL" | "decimal" => Ok(Self::Decimal),
71            _ => Err(FoundationError::ParseError {
72                type_name: "TabAlign".to_string(),
73                value: s.to_string(),
74                valid_values: "Left, Right, Center, Decimal".to_string(),
75            }),
76        }
77    }
78}
79
80impl schemars::JsonSchema for TabAlign {
81    fn schema_name() -> std::borrow::Cow<'static, str> {
82        std::borrow::Cow::Borrowed("TabAlign")
83    }
84
85    fn json_schema(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
86        gen.subschema_for::<String>()
87    }
88}
89
90// ---------------------------------------------------------------------------
91// TabLeader
92// ---------------------------------------------------------------------------
93
94/// Tab leader line style.
95///
96/// Stored as an uppercase HWPX-compatible string so unknown vendor values
97/// survive roundtrip instead of being silently flattened.
98#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
99#[serde(transparent)]
100pub struct TabLeader(String);
101
102impl TabLeader {
103    /// Creates a leader from a HWPX line type string.
104    pub fn from_hwpx_str(s: &str) -> Self {
105        Self(s.to_ascii_uppercase())
106    }
107
108    /// Returns the canonical HWPX string.
109    pub fn as_hwpx_str(&self) -> &str {
110        &self.0
111    }
112
113    /// No leader.
114    pub fn none() -> Self {
115        Self::from_hwpx_str("NONE")
116    }
117
118    /// Dotted leader.
119    pub fn dot() -> Self {
120        Self::from_hwpx_str("DOT")
121    }
122}
123
124impl fmt::Display for TabLeader {
125    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126        f.write_str(self.as_hwpx_str())
127    }
128}
129
130impl std::str::FromStr for TabLeader {
131    type Err = FoundationError;
132
133    fn from_str(s: &str) -> Result<Self, Self::Err> {
134        Ok(Self::from_hwpx_str(s))
135    }
136}
137
138impl schemars::JsonSchema for TabLeader {
139    fn schema_name() -> std::borrow::Cow<'static, str> {
140        std::borrow::Cow::Borrowed("TabLeader")
141    }
142
143    fn json_schema(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
144        gen.subschema_for::<String>()
145    }
146}