open_lark/service/cloud_docs/sheets/v3/condition_format/
create.rs1use reqwest::Method;
2use serde::{Deserialize, Serialize};
3
4use crate::{
5 core::{
6 api_req::ApiRequest,
7 api_resp::{ApiResponseTrait, BaseResponse, ResponseFormat},
8 constants::AccessTokenType,
9 endpoints::cloud_docs::*,
10 http::Transport,
11 req_option::RequestOption,
12 SDKResult,
13 },
14 impl_executable_builder_owned,
15 service::sheets::v3::SpreadsheetSheetService,
16};
17
18impl SpreadsheetSheetService {
19 pub async fn create_condition_formats(
21 &self,
22 request: CreateConditionFormatsRequest,
23 option: Option<RequestOption>,
24 ) -> SDKResult<BaseResponse<CreateConditionFormatsResponseData>> {
25 let mut api_req = request.api_request;
26 api_req.http_method = Method::POST;
27 api_req.api_path = SHEETS_V3_SPREADSHEET_CONDITION_FORMAT
28 .replace("{}", &request.spreadsheet_token)
29 .replace("{}", &request.sheet_id);
30 api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
31
32 let api_resp = Transport::request(api_req, &self.config, option).await?;
33
34 Ok(api_resp)
35 }
36}
37
38#[derive(Default, Debug, Serialize, Deserialize)]
40pub struct CreateConditionFormatsRequest {
41 #[serde(skip)]
42 api_request: ApiRequest,
43 spreadsheet_token: String,
45 sheet_id: String,
47 condition_formats: Vec<ConditionFormatRule>,
49}
50
51impl CreateConditionFormatsRequest {
52 pub fn builder() -> CreateConditionFormatsRequestBuilder {
53 CreateConditionFormatsRequestBuilder::default()
54 }
55}
56
57#[derive(Default)]
58pub struct CreateConditionFormatsRequestBuilder {
59 request: CreateConditionFormatsRequest,
60}
61
62impl CreateConditionFormatsRequestBuilder {
63 pub fn spreadsheet_token(mut self, spreadsheet_token: impl ToString) -> Self {
64 self.request.spreadsheet_token = spreadsheet_token.to_string();
65 self
66 }
67
68 pub fn sheet_id(mut self, sheet_id: impl ToString) -> Self {
69 self.request.sheet_id = sheet_id.to_string();
70 self
71 }
72
73 pub fn condition_formats(mut self, condition_formats: Vec<ConditionFormatRule>) -> Self {
74 self.request.condition_formats = condition_formats;
75 self
76 }
77
78 pub fn add_condition_format(mut self, condition_format: ConditionFormatRule) -> Self {
79 self.request.condition_formats.push(condition_format);
80 self
81 }
82
83 pub fn build(mut self) -> CreateConditionFormatsRequest {
84 self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
85 self.request
86 }
87}
88
89#[derive(Default, Debug, Serialize, Deserialize)]
91pub struct ConditionFormatRule {
92 pub range: String,
94 pub condition_type: String,
96 #[serde(skip_serializing_if = "Option::is_none")]
98 pub condition_values: Option<Vec<String>>,
99 pub format: FormatStyle,
101 #[serde(skip_serializing_if = "Option::is_none")]
103 pub cf_id: Option<String>,
104}
105
106#[derive(Default, Debug, Serialize, Deserialize)]
108pub struct FormatStyle {
109 #[serde(skip_serializing_if = "Option::is_none")]
111 pub background_color: Option<String>,
112 #[serde(skip_serializing_if = "Option::is_none")]
114 pub text_color: Option<String>,
115 #[serde(skip_serializing_if = "Option::is_none")]
117 pub bold: Option<bool>,
118 #[serde(skip_serializing_if = "Option::is_none")]
120 pub italic: Option<bool>,
121 #[serde(skip_serializing_if = "Option::is_none")]
123 pub underline: Option<bool>,
124 #[serde(skip_serializing_if = "Option::is_none")]
126 pub strikethrough: Option<bool>,
127}
128
129impl ConditionFormatRule {
130 pub fn number_comparison(
132 range: impl ToString,
133 comparison_type: impl ToString,
134 value: f64,
135 format: FormatStyle,
136 ) -> Self {
137 Self {
138 range: range.to_string(),
139 condition_type: comparison_type.to_string(),
140 condition_values: Some(vec![value.to_string()]),
141 format,
142 cf_id: None,
143 }
144 }
145
146 pub fn greater_than(range: impl ToString, value: f64, format: FormatStyle) -> Self {
148 Self::number_comparison(range, "NUMBER_GREATER", value, format)
149 }
150
151 pub fn less_than(range: impl ToString, value: f64, format: FormatStyle) -> Self {
153 Self::number_comparison(range, "NUMBER_LESS", value, format)
154 }
155
156 pub fn equal_to(range: impl ToString, value: f64, format: FormatStyle) -> Self {
158 Self::number_comparison(range, "NUMBER_EQ", value, format)
159 }
160
161 pub fn text_contains(range: impl ToString, text: impl ToString, format: FormatStyle) -> Self {
163 Self {
164 range: range.to_string(),
165 condition_type: "TEXT_CONTAINS".to_string(),
166 condition_values: Some(vec![text.to_string()]),
167 format,
168 cf_id: None,
169 }
170 }
171
172 pub fn duplicate_values(range: impl ToString, format: FormatStyle) -> Self {
174 Self {
175 range: range.to_string(),
176 condition_type: "DUPLICATE".to_string(),
177 condition_values: None,
178 format,
179 cf_id: None,
180 }
181 }
182
183 pub fn blank_values(range: impl ToString, format: FormatStyle) -> Self {
185 Self {
186 range: range.to_string(),
187 condition_type: "BLANK".to_string(),
188 condition_values: None,
189 format,
190 cf_id: None,
191 }
192 }
193}
194
195impl FormatStyle {
196 pub fn background_color(color: impl ToString) -> Self {
198 Self {
199 background_color: Some(color.to_string()),
200 text_color: None,
201 bold: None,
202 italic: None,
203 underline: None,
204 strikethrough: None,
205 }
206 }
207
208 pub fn text_color(color: impl ToString) -> Self {
210 Self {
211 background_color: None,
212 text_color: Some(color.to_string()),
213 bold: None,
214 italic: None,
215 underline: None,
216 strikethrough: None,
217 }
218 }
219
220 pub fn font_style(bold: bool, italic: bool, underline: bool) -> Self {
222 Self {
223 background_color: None,
224 text_color: None,
225 bold: Some(bold),
226 italic: Some(italic),
227 underline: Some(underline),
228 strikethrough: None,
229 }
230 }
231
232 pub fn with_background_color(mut self, color: impl ToString) -> Self {
234 self.background_color = Some(color.to_string());
235 self
236 }
237
238 pub fn with_text_color(mut self, color: impl ToString) -> Self {
240 self.text_color = Some(color.to_string());
241 self
242 }
243
244 pub fn with_bold(mut self, bold: bool) -> Self {
246 self.bold = Some(bold);
247 self
248 }
249
250 pub fn with_italic(mut self, italic: bool) -> Self {
252 self.italic = Some(italic);
253 self
254 }
255
256 pub fn with_underline(mut self, underline: bool) -> Self {
258 self.underline = Some(underline);
259 self
260 }
261
262 pub fn with_strikethrough(mut self, strikethrough: bool) -> Self {
264 self.strikethrough = Some(strikethrough);
265 self
266 }
267}
268
269#[derive(Deserialize, Debug)]
271pub struct ConditionFormatInfo {
272 pub cf_id: String,
274 #[serde(flatten)]
276 pub condition_format: ConditionFormatRule,
277}
278
279#[derive(Deserialize, Debug)]
281pub struct CreateConditionFormatsResponseData {
282 pub items: Vec<ConditionFormatInfo>,
284 #[serde(default)]
286 pub created_count: u32,
287}
288
289impl ApiResponseTrait for CreateConditionFormatsResponseData {
290 fn data_format() -> ResponseFormat {
291 ResponseFormat::Data
292 }
293}
294
295impl_executable_builder_owned!(
296 CreateConditionFormatsRequestBuilder,
297 SpreadsheetSheetService,
298 CreateConditionFormatsRequest,
299 BaseResponse<CreateConditionFormatsResponseData>,
300 create_condition_formats
301);
302
303#[cfg(test)]
304#[allow(unused_variables, unused_unsafe)]
305mod test {
306 use super::*;
307 use serde_json::json;
308
309 #[test]
310 fn test_condition_format_rule_creation() {
311 let format = FormatStyle::background_color("#FF0000").with_text_color("#FFFFFF");
312 let rule = ConditionFormatRule::greater_than("A1:A10", 100.0, format);
313
314 assert_eq!(rule.range, "A1:A10");
315 assert_eq!(rule.condition_type, "NUMBER_GREATER");
316 assert_eq!(rule.condition_values.as_ref().unwrap()[0], "100");
317 assert_eq!(rule.format.background_color.as_ref().unwrap(), "#FF0000");
318 assert_eq!(rule.format.text_color.as_ref().unwrap(), "#FFFFFF");
319 }
320
321 #[test]
322 fn test_create_condition_formats_response() {
323 let json = json!({
324 "items": [
325 {
326 "cf_id": "cf_001",
327 "range": "A1:A10",
328 "condition_type": "NUMBER_GREATER",
329 "condition_values": ["100"],
330 "format": {
331 "background_color": "#FF0000",
332 "text_color": "#FFFFFF",
333 "bold": true
334 }
335 }
336 ],
337 "created_count": 1
338 });
339
340 let response: CreateConditionFormatsResponseData = serde_json::from_value(json).unwrap();
341 assert_eq!(response.items.len(), 1);
342 assert_eq!(response.items[0].cf_id, "cf_001");
343 assert_eq!(response.created_count, 1);
344 }
345}