open_lark/service/cloud_docs/sheets/v2/data_operation/
split_cells.rs1use serde::{Deserialize, Serialize};
2
3use crate::{
4 core::{
5 api_req::ApiRequest,
6 api_resp::{ApiResponseTrait, BaseResponse, ResponseFormat},
7 constants::AccessTokenType,
8 endpoints::cloud_docs::*,
9 req_option, SDKResult,
10 },
11 service::cloud_docs::sheets::v2::SpreadsheetService,
12};
13
14#[derive(Serialize, Debug, Default)]
16pub struct SplitCellsRequest {
17 #[serde(skip)]
18 api_request: ApiRequest,
19 #[serde(skip)]
20 spreadsheet_token: String,
21 range: String,
23}
24
25impl SplitCellsRequest {
26 pub fn builder() -> SplitCellsRequestBuilder {
27 SplitCellsRequestBuilder::default()
28 }
29}
30
31#[derive(Default)]
32pub struct SplitCellsRequestBuilder {
33 request: SplitCellsRequest,
34}
35
36impl SplitCellsRequestBuilder {
37 pub fn spreadsheet_token(mut self, spreadsheet_token: impl ToString) -> Self {
38 self.request.spreadsheet_token = spreadsheet_token.to_string();
39 self
40 }
41
42 pub fn range(mut self, range: impl ToString) -> Self {
44 self.request.range = range.to_string();
45 self
46 }
47
48 pub fn build(mut self) -> SplitCellsRequest {
49 self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
50 self.request
51 }
52}
53
54#[derive(Deserialize, Debug)]
55pub struct SplitCellsResponse {
56 #[serde(rename = "spreadsheetToken")]
58 pub spread_sheet_token: String,
59}
60
61impl ApiResponseTrait for SplitCellsResponse {
62 fn data_format() -> ResponseFormat {
63 ResponseFormat::Data
64 }
65}
66
67impl SpreadsheetService {
68 pub async fn split_cells(
70 &self,
71 request: SplitCellsRequest,
72 option: Option<req_option::RequestOption>,
73 ) -> SDKResult<BaseResponse<SplitCellsResponse>> {
74 let mut api_req = request.api_request;
75 api_req.api_path =
76 SHEETS_V2_SPREADSHEET_UNMERGE_CELLS.replace("{}", &request.spreadsheet_token);
77 api_req.http_method = reqwest::Method::POST;
78 api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::App];
79
80 let api_resp = crate::core::http::Transport::request(api_req, &self.config, option).await?;
81
82 Ok(api_resp)
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use crate::{
89 core::{config::Config, constants::AppType},
90 service::cloud_docs::sheets::v2::{
91 data_operation::{SplitCellsRequest, SplitCellsResponse},
92 SpreadsheetService,
93 },
94 };
95
96 fn create_service() -> SpreadsheetService {
97 let config = Config::builder()
98 .app_id("test_app_id")
99 .app_secret("test_app_secret")
100 .app_type(AppType::SelfBuild)
101 .build();
102 SpreadsheetService { config }
103 }
104
105 #[test]
106 fn test_split_cells_builder_default() {
107 let request = SplitCellsRequest::builder().build();
108
109 assert_eq!(request.spreadsheet_token, "");
110 assert_eq!(request.range, "");
111 }
112
113 #[test]
114 fn test_split_cells_builder_basic() {
115 let request = SplitCellsRequest::builder()
116 .spreadsheet_token("test_token")
117 .range("Sheet1!A1:B2")
118 .build();
119
120 assert_eq!(request.spreadsheet_token, "test_token");
121 assert_eq!(request.range, "Sheet1!A1:B2");
122 }
123
124 #[test]
125 fn test_split_cells_builder_all_options() {
126 let request = SplitCellsRequest::builder()
127 .spreadsheet_token("spreadsheet_abc123")
128 .range("Data!C3:F6")
129 .build();
130
131 assert_eq!(request.spreadsheet_token, "spreadsheet_abc123");
132 assert_eq!(request.range, "Data!C3:F6");
133 }
134
135 #[test]
136 fn test_split_cells_builder_chaining() {
137 let request = SplitCellsRequest::builder()
138 .spreadsheet_token("chain_test")
139 .range("Summary!A1:D1")
140 .build();
141
142 assert_eq!(request.spreadsheet_token, "chain_test");
143 assert_eq!(request.range, "Summary!A1:D1");
144 }
145
146 #[test]
147 fn test_split_cells_single_merged_cell() {
148 let request = SplitCellsRequest::builder()
149 .spreadsheet_token("single_cell_test")
150 .range("Sheet1!A1:A1")
151 .build();
152
153 assert_eq!(request.spreadsheet_token, "single_cell_test");
154 assert_eq!(request.range, "Sheet1!A1:A1");
155 }
156
157 #[test]
158 fn test_split_cells_large_merged_range() {
159 let request = SplitCellsRequest::builder()
160 .spreadsheet_token("large_range_test")
161 .range("Data!A1:Z100")
162 .build();
163
164 assert_eq!(request.spreadsheet_token, "large_range_test");
165 assert_eq!(request.range, "Data!A1:Z100");
166 }
167
168 #[test]
169 fn test_split_cells_row_range() {
170 let request = SplitCellsRequest::builder()
171 .spreadsheet_token("row_range_test")
172 .range("Sheet1!A1:Z1")
173 .build();
174
175 assert_eq!(request.spreadsheet_token, "row_range_test");
176 assert_eq!(request.range, "Sheet1!A1:Z1");
177 }
178
179 #[test]
180 fn test_split_cells_column_range() {
181 let request = SplitCellsRequest::builder()
182 .spreadsheet_token("column_range_test")
183 .range("Sheet1!A1:A50")
184 .build();
185
186 assert_eq!(request.spreadsheet_token, "column_range_test");
187 assert_eq!(request.range, "Sheet1!A1:A50");
188 }
189
190 #[test]
191 fn test_split_cells_with_unicode_ranges() {
192 let request = SplitCellsRequest::builder()
193 .spreadsheet_token("unicode_test")
194 .range("数据表!A1:D4")
195 .build();
196
197 assert_eq!(request.spreadsheet_token, "unicode_test");
198 assert_eq!(request.range, "数据表!A1:D4");
199 }
200
201 #[test]
202 fn test_split_cells_with_special_characters() {
203 let request = SplitCellsRequest::builder()
204 .spreadsheet_token("special_chars_test")
205 .range("'Sheet With Spaces'!A1:B5")
206 .build();
207
208 assert_eq!(request.spreadsheet_token, "special_chars_test");
209 assert_eq!(request.range, "'Sheet With Spaces'!A1:B5");
210 }
211
212 #[test]
213 fn test_split_cells_different_sheets() {
214 let sheets_and_ranges = [
215 ("Sheet1", "A1:B2"),
216 ("Summary", "C1:F1"),
217 ("Data", "A5:D10"),
218 ("第一页", "B3:E8"),
219 ];
220
221 for (sheet, range) in sheets_and_ranges.iter() {
222 let full_range = format!("{}!{}", sheet, range);
223 let request = SplitCellsRequest::builder()
224 .spreadsheet_token("multi_sheet_test")
225 .range(&full_range)
226 .build();
227
228 assert_eq!(request.range, full_range);
229 }
230 }
231
232 #[test]
233 fn test_split_cells_serialization() {
234 let request = SplitCellsRequest::builder()
235 .spreadsheet_token("serialization_test")
236 .range("Sheet1!A1:C3")
237 .build();
238
239 let serialized = serde_json::to_string(&request);
240 assert!(serialized.is_ok());
241
242 let json_value: serde_json::Value = serde_json::from_str(&serialized.unwrap()).unwrap();
243 assert_eq!(json_value["range"], "Sheet1!A1:C3");
244 }
245
246 #[test]
247 fn test_split_cells_response_deserialization() {
248 let response_json = serde_json::json!({
249 "spreadsheetToken": "test_token_123"
250 });
251
252 let response: SplitCellsResponse = serde_json::from_value(response_json).unwrap();
253
254 assert_eq!(response.spread_sheet_token, "test_token_123");
255 }
256
257 #[test]
258 fn test_split_cells_complex_range_references() {
259 let complex_ranges = vec![
260 "Sheet1!A1:D5",
261 "'Data Sheet'!B2:F10",
262 "工作表!C3:G7",
263 "Sheet-Name_123!A10:E15",
264 "'Sheet (1)'!D1:H4",
265 ];
266
267 for range in complex_ranges {
268 let request = SplitCellsRequest::builder()
269 .spreadsheet_token("complex_ref_test")
270 .range(range)
271 .build();
272
273 assert_eq!(request.range, range);
274 }
275 }
276
277 #[test]
278 fn test_split_cells_service_creation() {
279 let service = create_service();
280 assert_eq!(service.config.app_id, "test_app_id");
281 assert_eq!(service.config.app_secret, "test_app_secret");
282 assert!(matches!(service.config.app_type, AppType::SelfBuild));
283 }
284
285 #[test]
286 fn test_split_cells_builder_overwrites() {
287 let request = SplitCellsRequest::builder()
288 .spreadsheet_token("original_token")
289 .spreadsheet_token("final_token") .range("Sheet1!A1:B2")
291 .range("Sheet2!C3:D4") .build();
293
294 assert_eq!(request.spreadsheet_token, "final_token");
295 assert_eq!(request.range, "Sheet2!C3:D4");
296 }
297
298 #[test]
299 fn test_split_cells_very_long_token() {
300 let very_long_token = "a".repeat(1000);
301 let request = SplitCellsRequest::builder()
302 .spreadsheet_token(&very_long_token)
303 .range("Sheet1!A1:B2")
304 .build();
305
306 assert_eq!(request.spreadsheet_token, very_long_token);
307 assert_eq!(request.range, "Sheet1!A1:B2");
308 }
309
310 #[test]
311 fn test_split_cells_response_struct_debug() {
312 let response = SplitCellsResponse {
313 spread_sheet_token: "debug_test".to_string(),
314 };
315
316 let debug_str = format!("{:?}", response);
317 assert!(debug_str.contains("debug_test"));
318 assert!(debug_str.contains("SplitCellsResponse"));
319 }
320
321 #[test]
322 fn test_split_cells_request_struct_debug() {
323 let request = SplitCellsRequest::builder()
324 .spreadsheet_token("debug_token")
325 .range("Sheet1!A1:B2")
326 .build();
327
328 let debug_str = format!("{:?}", request);
329 assert!(debug_str.contains("debug_token"));
330 assert!(debug_str.contains("Sheet1!A1:B2"));
331 }
332
333 #[test]
334 fn test_split_cells_empty_strings() {
335 let request = SplitCellsRequest::builder()
336 .spreadsheet_token("")
337 .range("")
338 .build();
339
340 assert_eq!(request.spreadsheet_token, "");
341 assert_eq!(request.range, "");
342 }
343
344 #[test]
345 fn test_split_cells_multiple_merged_areas() {
346 let merged_areas = vec![
347 "Sheet1!A1:B2", "Sheet1!D1:G1", "Sheet1!A5:A10", "Sheet1!C3:E5", ];
352
353 for range in merged_areas {
354 let request = SplitCellsRequest::builder()
355 .spreadsheet_token("multiple_areas_test")
356 .range(range)
357 .build();
358
359 assert_eq!(request.range, range);
360 }
361 }
362
363 #[test]
364 fn test_split_cells_large_spreadsheet_ranges() {
365 let large_ranges = vec![
366 "Sheet1!A1:ZZ1000", "Data!A1:IV65536", "Report!AA1:ZZ100", ];
370
371 for range in large_ranges {
372 let request = SplitCellsRequest::builder()
373 .spreadsheet_token("large_spreadsheet_test")
374 .range(range)
375 .build();
376
377 assert_eq!(request.range, range);
378 }
379 }
380
381 #[test]
382 fn test_split_cells_various_sheet_names() {
383 let sheet_names_with_ranges = vec![
384 ("普通工作表", "A1:B2"),
385 ("Sheet_123", "C1:D5"),
386 ("'Special-Name (1)'", "E1:F3"),
387 ("数据分析报表", "A10:C15"),
388 ("Sheet With Spaces", "G1:H2"),
389 ];
390
391 for (sheet_name, range) in sheet_names_with_ranges {
392 let full_range = if sheet_name.contains(' ') || sheet_name.contains('(') {
393 format!("'{}'!{}", sheet_name, range)
394 } else {
395 format!("{}!{}", sheet_name, range)
396 };
397
398 let request = SplitCellsRequest::builder()
399 .spreadsheet_token("various_sheets_test")
400 .range(&full_range)
401 .build();
402
403 assert_eq!(request.range, full_range);
404 }
405 }
406
407 #[test]
408 fn test_split_cells_edge_case_ranges() {
409 let edge_cases = vec![
410 "Sheet1!A1:A1", "Sheet1!A1:B1", "Sheet1!A1:A2", "Sheet1!Z99:AA100", ];
415
416 for range in edge_cases {
417 let request = SplitCellsRequest::builder()
418 .spreadsheet_token("edge_cases_test")
419 .range(range)
420 .build();
421
422 assert_eq!(request.range, range);
423 }
424 }
425}