1use schemars::JsonSchema;
2use serde::de;
3use serde::{Deserialize, Serialize};
4use std::fmt;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, JsonSchema)]
7#[serde(rename_all = "snake_case")]
8#[derive(Default)]
9pub enum BatchMode {
10 #[default]
11 Apply,
12 Preview,
13}
14
15impl BatchMode {
16 pub fn as_str(self) -> &'static str {
17 match self {
18 Self::Apply => "apply",
19 Self::Preview => "preview",
20 }
21 }
22
23 pub fn is_preview(self) -> bool {
24 matches!(self, Self::Preview)
25 }
26}
27
28impl fmt::Display for BatchMode {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 f.write_str(self.as_str())
31 }
32}
33
34impl<'de> Deserialize<'de> for BatchMode {
35 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
36 where
37 D: de::Deserializer<'de>,
38 {
39 let s = String::deserialize(deserializer)?;
40 match s.to_ascii_lowercase().as_str() {
41 "apply" => Ok(Self::Apply),
42 "preview" => Ok(Self::Preview),
43 other => Err(de::Error::unknown_variant(other, &["apply", "preview"])),
44 }
45 }
46}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, JsonSchema)]
49#[serde(rename_all = "snake_case")]
50#[derive(Default)]
51pub enum ReplaceMatchMode {
52 #[default]
53 Exact,
54 Contains,
55}
56
57impl ReplaceMatchMode {
58 pub fn as_str(self) -> &'static str {
59 match self {
60 Self::Exact => "exact",
61 Self::Contains => "contains",
62 }
63 }
64}
65
66impl<'de> Deserialize<'de> for ReplaceMatchMode {
67 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
68 where
69 D: de::Deserializer<'de>,
70 {
71 let s = String::deserialize(deserializer)?;
72 match s.to_ascii_lowercase().as_str() {
73 "exact" => Ok(Self::Exact),
74 "contains" => Ok(Self::Contains),
75 other => Err(de::Error::unknown_variant(other, &["exact", "contains"])),
76 }
77 }
78}
79
80#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, JsonSchema)]
81#[serde(rename_all = "snake_case")]
82#[derive(Default)]
83pub enum FillDirection {
84 Down,
85 Right,
86 #[default]
87 Both,
88}
89
90impl FillDirection {
91 pub fn as_str(self) -> &'static str {
92 match self {
93 Self::Down => "down",
94 Self::Right => "right",
95 Self::Both => "both",
96 }
97 }
98}
99
100impl<'de> Deserialize<'de> for FillDirection {
101 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
102 where
103 D: de::Deserializer<'de>,
104 {
105 let s = String::deserialize(deserializer)?;
106 match s.to_ascii_lowercase().as_str() {
107 "down" => Ok(Self::Down),
108 "right" => Ok(Self::Right),
109 "both" => Ok(Self::Both),
110 other => Err(de::Error::unknown_variant(
111 other,
112 &["down", "right", "both"],
113 )),
114 }
115 }
116}
117
118#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, JsonSchema)]
119#[serde(rename_all = "snake_case")]
120#[derive(Default)]
121pub enum FormulaRelativeMode {
122 #[default]
123 Excel,
124 AbsCols,
125 AbsRows,
126}
127
128impl<'de> Deserialize<'de> for FormulaRelativeMode {
129 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
130 where
131 D: de::Deserializer<'de>,
132 {
133 let s = String::deserialize(deserializer)?;
134 match s.to_ascii_lowercase().as_str() {
135 "excel" => Ok(Self::Excel),
136 "abs_cols" | "abscols" | "columns_absolute" => Ok(Self::AbsCols),
137 "abs_rows" | "absrows" | "rows_absolute" => Ok(Self::AbsRows),
138 other => Err(de::Error::unknown_variant(
139 other,
140 &["excel", "abs_cols", "abs_rows"],
141 )),
142 }
143 }
144}
145
146impl From<FormulaRelativeMode> for crate::formula::pattern::RelativeMode {
147 fn from(value: FormulaRelativeMode) -> Self {
148 match value {
149 FormulaRelativeMode::Excel => Self::Excel,
150 FormulaRelativeMode::AbsCols => Self::AbsCols,
151 FormulaRelativeMode::AbsRows => Self::AbsRows,
152 }
153 }
154}
155
156#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, JsonSchema)]
157#[serde(rename_all = "snake_case")]
158pub enum PageOrientation {
159 Portrait,
160 Landscape,
161}
162
163impl<'de> Deserialize<'de> for PageOrientation {
164 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
165 where
166 D: de::Deserializer<'de>,
167 {
168 let s = String::deserialize(deserializer)?;
169 match s.to_ascii_lowercase().as_str() {
170 "portrait" => Ok(Self::Portrait),
171 "landscape" => Ok(Self::Landscape),
172 other => Err(de::Error::unknown_variant(
173 other,
174 &["portrait", "landscape"],
175 )),
176 }
177 }
178}
179
180impl PageOrientation {
181 pub fn to_umya(self) -> umya_spreadsheet::OrientationValues {
182 match self {
183 Self::Portrait => umya_spreadsheet::OrientationValues::Portrait,
184 Self::Landscape => umya_spreadsheet::OrientationValues::Landscape,
185 }
186 }
187}