open_lark/service/cloud_docs/sheets/v3/data_validation/
create.rs

1use 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    /// 设置下拉列表
20    pub async fn set_data_validation(
21        &self,
22        request: SetDataValidationRequest,
23        option: Option<RequestOption>,
24    ) -> SDKResult<BaseResponse<SetDataValidationResponseData>> {
25        let mut api_req = request.api_request;
26        api_req.http_method = Method::POST;
27        api_req.api_path = SHEETS_V3_SPREADSHEET_DATA_VALIDATION
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/// 设置下拉列表请求
39#[derive(Default, Debug, Serialize, Deserialize)]
40pub struct SetDataValidationRequest {
41    #[serde(skip)]
42    api_request: ApiRequest,
43    /// spreadsheet 的 token
44    spreadsheet_token: String,
45    /// sheet 的 id
46    sheet_id: String,
47    /// 数据校验设置
48    data_validation: DataValidationRule,
49}
50
51impl SetDataValidationRequest {
52    pub fn builder() -> SetDataValidationRequestBuilder {
53        SetDataValidationRequestBuilder::default()
54    }
55}
56
57#[derive(Default)]
58pub struct SetDataValidationRequestBuilder {
59    request: SetDataValidationRequest,
60}
61
62impl SetDataValidationRequestBuilder {
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 data_validation(mut self, data_validation: DataValidationRule) -> Self {
74        self.request.data_validation = data_validation;
75        self
76    }
77
78    pub fn build(mut self) -> SetDataValidationRequest {
79        self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
80        self.request
81    }
82}
83
84/// 数据校验规则
85#[derive(Default, Debug, Serialize, Deserialize)]
86pub struct DataValidationRule {
87    /// 数据校验类型
88    pub condition_type: String,
89    /// 应用范围
90    pub range: String,
91    /// 校验条件值
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub condition_values: Option<Vec<String>>,
94    /// 是否拒绝输入
95    #[serde(default)]
96    pub strict: bool,
97    /// 输入提示消息
98    #[serde(skip_serializing_if = "Option::is_none")]
99    pub input_message: Option<String>,
100    /// 错误提示消息
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub error_message: Option<String>,
103    /// 数据校验 ID(仅在响应时存在)
104    #[serde(skip_serializing_if = "Option::is_none")]
105    pub data_validation_id: Option<String>,
106}
107
108impl DataValidationRule {
109    /// 创建下拉列表校验
110    pub fn dropdown(range: impl ToString, options: Vec<String>) -> Self {
111        Self {
112            condition_type: "dropdown".to_string(),
113            range: range.to_string(),
114            condition_values: Some(options),
115            strict: true,
116            input_message: None,
117            error_message: None,
118            data_validation_id: None,
119        }
120    }
121
122    /// 创建数字范围校验
123    pub fn number_range(range: impl ToString, min: f64, max: f64) -> Self {
124        Self {
125            condition_type: "number_between".to_string(),
126            range: range.to_string(),
127            condition_values: Some(vec![min.to_string(), max.to_string()]),
128            strict: true,
129            input_message: None,
130            error_message: None,
131            data_validation_id: None,
132        }
133    }
134
135    /// 创建文本长度校验
136    pub fn text_length(range: impl ToString, min_length: u32, max_length: u32) -> Self {
137        Self {
138            condition_type: "text_length".to_string(),
139            range: range.to_string(),
140            condition_values: Some(vec![min_length.to_string(), max_length.to_string()]),
141            strict: true,
142            input_message: None,
143            error_message: None,
144            data_validation_id: None,
145        }
146    }
147
148    /// 设置输入提示
149    pub fn with_input_message(mut self, message: impl ToString) -> Self {
150        self.input_message = Some(message.to_string());
151        self
152    }
153
154    /// 设置错误提示
155    pub fn with_error_message(mut self, message: impl ToString) -> Self {
156        self.error_message = Some(message.to_string());
157        self
158    }
159
160    /// 设置是否严格模式
161    pub fn with_strict(mut self, strict: bool) -> Self {
162        self.strict = strict;
163        self
164    }
165}
166
167/// 设置下拉列表响应体最外层
168#[derive(Deserialize, Debug)]
169pub struct SetDataValidationResponseData {
170    /// 数据校验 ID
171    pub data_validation_id: String,
172    /// 数据校验规则信息
173    #[serde(flatten)]
174    pub data_validation: DataValidationRule,
175}
176
177impl ApiResponseTrait for SetDataValidationResponseData {
178    fn data_format() -> ResponseFormat {
179        ResponseFormat::Data
180    }
181}
182
183#[cfg(test)]
184#[allow(unused_variables, unused_unsafe)]
185mod test {
186    use super::*;
187    use serde_json::json;
188
189    #[test]
190    fn test_data_validation_rule_creation() {
191        let validation =
192            DataValidationRule::dropdown("A1:A10", vec!["选项1".to_string(), "选项2".to_string()]);
193        assert_eq!(validation.condition_type, "dropdown");
194        assert_eq!(validation.range, "A1:A10");
195        assert!(validation.strict);
196        assert_eq!(validation.condition_values.as_ref().unwrap().len(), 2);
197    }
198
199    #[test]
200    fn test_set_data_validation_response() {
201        let json = json!({
202            "data_validation_id": "dv_001",
203            "condition_type": "dropdown",
204            "range": "A1:A10",
205            "condition_values": ["选项1", "选项2"],
206            "strict": true,
207            "input_message": "请选择一个选项",
208            "error_message": "输入无效"
209        });
210
211        let response: SetDataValidationResponseData = serde_json::from_value(json).unwrap();
212        assert_eq!(response.data_validation_id, "dv_001");
213        assert_eq!(response.data_validation.condition_type, "dropdown");
214    }
215}
216
217// 实现ExecutableBuilder trait
218impl_executable_builder_owned!(
219    SetDataValidationRequestBuilder,
220    SpreadsheetSheetService,
221    SetDataValidationRequest,
222    BaseResponse<SetDataValidationResponseData>,
223    set_data_validation
224);