Skip to main content

spreadsheet_mcp/tools/
param_enums.rs

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}