1use crate::error::Result;
7
8#[derive(Debug, Clone)]
10pub struct SlicerConfig {
11 pub name: String,
13 pub cell: String,
15 pub table_name: String,
17 pub column_name: String,
19 pub caption: Option<String>,
21 pub style: Option<String>,
23 pub width: Option<u32>,
25 pub height: Option<u32>,
27 pub show_caption: Option<bool>,
29 pub column_count: Option<u32>,
31}
32
33#[derive(Debug, Clone)]
35pub struct SlicerInfo {
36 pub name: String,
38 pub caption: String,
40 pub table_name: String,
42 pub column_name: String,
44 pub style: Option<String>,
46}
47
48pub const DEFAULT_ROW_HEIGHT_EMU: u32 = 241300;
50
51pub const DEFAULT_WIDTH_PX: u32 = 200;
53
54pub const DEFAULT_HEIGHT_PX: u32 = 200;
56
57pub const PX_TO_EMU: u64 = 9525;
59
60pub fn validate_slicer_config(config: &SlicerConfig) -> Result<()> {
62 if config.name.is_empty() {
63 return Err(crate::error::Error::InvalidArgument(
64 "slicer name cannot be empty".to_string(),
65 ));
66 }
67 if config.cell.is_empty() {
68 return Err(crate::error::Error::InvalidArgument(
69 "slicer anchor cell cannot be empty".to_string(),
70 ));
71 }
72 if config.table_name.is_empty() {
73 return Err(crate::error::Error::InvalidArgument(
74 "slicer table_name cannot be empty".to_string(),
75 ));
76 }
77 if config.column_name.is_empty() {
78 return Err(crate::error::Error::InvalidArgument(
79 "slicer column_name cannot be empty".to_string(),
80 ));
81 }
82 crate::utils::cell_ref::cell_name_to_coordinates(&config.cell)?;
84 Ok(())
85}
86
87pub fn slicer_cache_name(name: &str) -> String {
89 format!("Slicer_{}", name.replace(' ', "_"))
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 #[test]
97 fn test_validate_slicer_config_valid() {
98 let config = SlicerConfig {
99 name: "StatusFilter".to_string(),
100 cell: "F1".to_string(),
101 table_name: "Table1".to_string(),
102 column_name: "Status".to_string(),
103 caption: None,
104 style: None,
105 width: None,
106 height: None,
107 show_caption: None,
108 column_count: None,
109 };
110 assert!(validate_slicer_config(&config).is_ok());
111 }
112
113 #[test]
114 fn test_validate_slicer_config_empty_name() {
115 let config = SlicerConfig {
116 name: "".to_string(),
117 cell: "A1".to_string(),
118 table_name: "T".to_string(),
119 column_name: "C".to_string(),
120 caption: None,
121 style: None,
122 width: None,
123 height: None,
124 show_caption: None,
125 column_count: None,
126 };
127 let err = validate_slicer_config(&config).unwrap_err();
128 assert!(err.to_string().contains("name cannot be empty"));
129 }
130
131 #[test]
132 fn test_validate_slicer_config_empty_cell() {
133 let config = SlicerConfig {
134 name: "S1".to_string(),
135 cell: "".to_string(),
136 table_name: "T".to_string(),
137 column_name: "C".to_string(),
138 caption: None,
139 style: None,
140 width: None,
141 height: None,
142 show_caption: None,
143 column_count: None,
144 };
145 let err = validate_slicer_config(&config).unwrap_err();
146 assert!(err.to_string().contains("cell cannot be empty"));
147 }
148
149 #[test]
150 fn test_validate_slicer_config_empty_table() {
151 let config = SlicerConfig {
152 name: "S1".to_string(),
153 cell: "A1".to_string(),
154 table_name: "".to_string(),
155 column_name: "C".to_string(),
156 caption: None,
157 style: None,
158 width: None,
159 height: None,
160 show_caption: None,
161 column_count: None,
162 };
163 let err = validate_slicer_config(&config).unwrap_err();
164 assert!(err.to_string().contains("table_name cannot be empty"));
165 }
166
167 #[test]
168 fn test_validate_slicer_config_empty_column() {
169 let config = SlicerConfig {
170 name: "S1".to_string(),
171 cell: "A1".to_string(),
172 table_name: "T".to_string(),
173 column_name: "".to_string(),
174 caption: None,
175 style: None,
176 width: None,
177 height: None,
178 show_caption: None,
179 column_count: None,
180 };
181 let err = validate_slicer_config(&config).unwrap_err();
182 assert!(err.to_string().contains("column_name cannot be empty"));
183 }
184
185 #[test]
186 fn test_validate_slicer_config_invalid_cell() {
187 let config = SlicerConfig {
188 name: "S1".to_string(),
189 cell: "XYZ0".to_string(),
190 table_name: "T".to_string(),
191 column_name: "C".to_string(),
192 caption: None,
193 style: None,
194 width: None,
195 height: None,
196 show_caption: None,
197 column_count: None,
198 };
199 assert!(validate_slicer_config(&config).is_err());
200 }
201
202 #[test]
203 fn test_slicer_cache_name() {
204 assert_eq!(slicer_cache_name("Category"), "Slicer_Category");
205 assert_eq!(slicer_cache_name("My Filter"), "Slicer_My_Filter");
206 }
207
208 #[test]
209 fn test_slicer_info_struct() {
210 let info = SlicerInfo {
211 name: "StatusFilter".to_string(),
212 caption: "Status".to_string(),
213 table_name: "Table1".to_string(),
214 column_name: "Status".to_string(),
215 style: Some("SlicerStyleLight1".to_string()),
216 };
217 assert_eq!(info.name, "StatusFilter");
218 assert_eq!(info.column_name, "Status");
219 }
220}