openlark_workflow/v2/custom_field/option/
create.rs1use 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#[derive(Debug, Clone, Serialize, Default)]
17pub struct CreateCustomFieldOptionBody {
18 pub name: String,
20 #[serde(skip_serializing_if = "Option::is_none")]
22 pub color: Option<String>,
23}
24
25#[derive(Debug, Clone, Deserialize)]
27pub struct CustomFieldOption {
28 pub option_guid: String,
30 pub name: String,
32 #[serde(default)]
34 pub color: Option<String>,
35 pub created_at: String,
37 pub updated_at: String,
39}
40
41#[derive(Debug, Clone, Deserialize)]
43pub struct CreateCustomFieldOptionResponse {
44 pub option: CustomFieldOption,
46}
47
48#[derive(Debug, Clone)]
50pub struct CreateCustomFieldOptionRequest {
51 config: Arc<Config>,
53 custom_field_guid: String,
55 body: CreateCustomFieldOptionBody,
57}
58
59impl CreateCustomFieldOptionRequest {
60 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 pub fn name(mut self, name: impl Into<String>) -> Self {
71 self.body.name = name.into();
72 self
73 }
74
75 pub fn color(mut self, color: impl Into<String>) -> Self {
77 self.body.color = Some(color.into());
78 self
79 }
80
81 pub async fn execute(self) -> SDKResult<CreateCustomFieldOptionResponse> {
83 self.execute_with_options(openlark_core::req_option::RequestOption::default())
84 .await
85 }
86
87 pub async fn execute_with_options(
89 self,
90 option: openlark_core::req_option::RequestOption,
91 ) -> SDKResult<CreateCustomFieldOptionResponse> {
92 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 let response =
104 openlark_core::http::Transport::request(request, &self.config, Some(option)).await?;
105 extract_response_data(response, "创建自定义字段选项")
106 }
107}
108
109impl ApiResponseTrait for CreateCustomFieldOptionResponse {
110 fn data_format() -> ResponseFormat {
111 ResponseFormat::Data
112 }
113}
114
115#[cfg(test)]
116#[allow(unused_imports)]
117mod tests {
118 use std::sync::Arc;
119
120 use super::*;
121
122 #[test]
123 fn test_create_custom_field_option_builder() {
124 let config = Arc::new(
125 openlark_core::config::Config::builder()
126 .app_id("test")
127 .app_secret("test")
128 .build(),
129 );
130
131 let request = CreateCustomFieldOptionRequest::new(config, "custom_field_123")
132 .name("高优先级")
133 .color("#FF0000");
134
135 assert_eq!(request.custom_field_guid, "custom_field_123");
136 assert_eq!(request.body.name, "高优先级");
137 assert_eq!(request.body.color, Some("#FF0000".to_string()));
138 }
139
140 #[test]
141 fn test_custom_field_option_create_api_v2_url() {
142 let endpoint = TaskApiV2::CustomFieldOptionCreate("custom_field_123".to_string());
143 assert_eq!(
144 endpoint.to_url(),
145 "/open-apis/task/v2/custom_fields/custom_field_123/options"
146 );
147 }
148}