Skip to main content

openlark_workflow/v2/custom_field/option/
create.rs

1//! 创建自定义字段选项
2//!
3//! docPath: <https://open.feishu.cn/document/server-docs/docs/task-v2/custom_field-option/create>
4
5use crate::common::{api_endpoints::TaskApiV2, api_utils::*};
6use openlark_core::{
7    SDKResult,
8    api::{ApiRequest, ApiResponseTrait, ResponseFormat},
9    config::Config,
10    validate_required,
11};
12use serde::{Deserialize, Serialize};
13use std::sync::Arc;
14
15/// 创建自定义字段选项请求体
16#[derive(Debug, Clone, Serialize, Default)]
17pub struct CreateCustomFieldOptionBody {
18    /// 选项名称
19    pub name: String,
20    /// 选项颜色(可选)
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub color: Option<String>,
23}
24
25/// 自定义字段选项信息
26#[derive(Debug, Clone, Deserialize)]
27pub struct CustomFieldOption {
28    /// 选项 GUID
29    pub option_guid: String,
30    /// 选项名称
31    pub name: String,
32    /// 选项颜色
33    #[serde(default)]
34    pub color: Option<String>,
35    /// 创建时间
36    pub created_at: String,
37    /// 更新时间
38    pub updated_at: String,
39}
40
41/// 创建自定义字段选项响应
42#[derive(Debug, Clone, Deserialize)]
43pub struct CreateCustomFieldOptionResponse {
44    /// 选项信息
45    pub option: CustomFieldOption,
46}
47
48/// 创建自定义字段选项请求
49#[derive(Debug, Clone)]
50pub struct CreateCustomFieldOptionRequest {
51    /// 配置信息
52    config: Arc<Config>,
53    /// 自定义字段 GUID
54    custom_field_guid: String,
55    /// 请求体
56    body: CreateCustomFieldOptionBody,
57}
58
59impl CreateCustomFieldOptionRequest {
60    /// 创建新的请求构建器。
61    pub fn new(config: Arc<Config>, custom_field_guid: impl Into<String>) -> Self {
62        Self {
63            config,
64            custom_field_guid: custom_field_guid.into(),
65            body: CreateCustomFieldOptionBody::default(),
66        }
67    }
68
69    /// 设置选项名称
70    pub fn name(mut self, name: impl Into<String>) -> Self {
71        self.body.name = name.into();
72        self
73    }
74
75    /// 设置选项颜色
76    pub fn color(mut self, color: impl Into<String>) -> Self {
77        self.body.color = Some(color.into());
78        self
79    }
80
81    /// 执行请求
82    pub async fn execute(self) -> SDKResult<CreateCustomFieldOptionResponse> {
83        self.execute_with_options(openlark_core::req_option::RequestOption::default())
84            .await
85    }
86
87    /// 执行请求(带选项)
88    pub async fn execute_with_options(
89        self,
90        option: openlark_core::req_option::RequestOption,
91    ) -> SDKResult<CreateCustomFieldOptionResponse> {
92        // 验证必填字段
93        validate_required!(self.custom_field_guid.trim(), "自定义字段GUID不能为空");
94        validate_required!(self.body.name.trim(), "选项名称不能为空");
95
96        let api_endpoint = TaskApiV2::CustomFieldOptionCreate(self.custom_field_guid.clone());
97        let mut request =
98            ApiRequest::<CreateCustomFieldOptionResponse>::post(api_endpoint.to_url());
99
100        let request_body = &self.body;
101        request = request.body(serialize_params(request_body, "创建自定义字段选项")?);
102
103        openlark_core::http::Transport::request_typed(
104            request,
105            &self.config,
106            Some(option),
107            "创建自定义字段选项",
108        )
109        .await
110    }
111}
112
113impl ApiResponseTrait for CreateCustomFieldOptionResponse {
114    fn data_format() -> ResponseFormat {
115        ResponseFormat::Data
116    }
117}
118
119#[cfg(test)]
120#[allow(unused_imports)]
121mod tests {
122    use std::sync::Arc;
123
124    use super::*;
125
126    #[test]
127    fn test_create_custom_field_option_builder() {
128        let config = Arc::new(
129            openlark_core::config::Config::builder()
130                .app_id("test")
131                .app_secret("test")
132                .build(),
133        );
134
135        let request = CreateCustomFieldOptionRequest::new(config, "custom_field_123")
136            .name("高优先级")
137            .color("#FF0000");
138
139        assert_eq!(request.custom_field_guid, "custom_field_123");
140        assert_eq!(request.body.name, "高优先级");
141        assert_eq!(request.body.color, Some("#FF0000".to_string()));
142    }
143
144    #[test]
145    fn test_custom_field_option_create_api_v2_url() {
146        let endpoint = TaskApiV2::CustomFieldOptionCreate("custom_field_123".to_string());
147        assert_eq!(
148            endpoint.to_url(),
149            "/open-apis/task/v2/custom_fields/custom_field_123/options"
150        );
151    }
152}