open_lark/service/cloud_docs/bitable/v1/app/
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        http::Transport,
10        req_option::RequestOption,
11        SDKResult,
12    },
13    impl_executable_builder_owned,
14};
15
16use super::AppService;
17
18impl AppService {
19    /// 创建多维表格
20    ///
21    /// <https://open.feishu.cn/document/server-docs/docs/bitable-v1/app/create>
22    pub async fn create(
23        &self,
24        request: CreateAppRequest,
25        option: Option<RequestOption>,
26    ) -> SDKResult<BaseResponse<CreateAppResponse>> {
27        let mut api_req = request.api_request;
28        api_req.http_method = Method::POST;
29        api_req.api_path = "/open-apis/bitable/v1/apps".to_string();
30        api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
31        api_req.body = serde_json::to_vec(&CreateAppRequestBody {
32            name: request.name,
33            folder_token: request.folder_token,
34            time_zone: request.time_zone,
35        })?;
36
37        let api_resp = Transport::request(api_req, &self.config, option).await?;
38        Ok(api_resp)
39    }
40}
41
42/// 创建多维表格请求
43#[derive(Debug, Default)]
44pub struct CreateAppRequest {
45    api_request: ApiRequest,
46    /// 多维表格 App 名字
47    name: String,
48    /// 多维表格所在文件夹的 token,若不传则默认添加到用户云空间的根目录下
49    folder_token: Option<String>,
50    /// 时区
51    time_zone: Option<String>,
52}
53
54impl CreateAppRequest {
55    pub fn builder() -> CreateAppRequestBuilder {
56        CreateAppRequestBuilder::default()
57    }
58}
59
60#[derive(Default)]
61pub struct CreateAppRequestBuilder {
62    request: CreateAppRequest,
63}
64
65impl CreateAppRequestBuilder {
66    /// 多维表格 App 名字
67    pub fn name(mut self, name: impl ToString) -> Self {
68        self.request.name = name.to_string();
69        self
70    }
71
72    /// 多维表格所在文件夹的 token
73    pub fn folder_token(mut self, folder_token: impl ToString) -> Self {
74        self.request.folder_token = Some(folder_token.to_string());
75        self
76    }
77
78    /// 时区
79    pub fn time_zone(mut self, time_zone: impl ToString) -> Self {
80        self.request.time_zone = Some(time_zone.to_string());
81        self
82    }
83
84    pub fn build(self) -> CreateAppRequest {
85        self.request
86    }
87}
88
89impl_executable_builder_owned!(
90    CreateAppRequestBuilder,
91    AppService,
92    CreateAppRequest,
93    BaseResponse<CreateAppResponse>,
94    create
95);
96
97#[derive(Serialize)]
98struct CreateAppRequestBody {
99    name: String,
100    #[serde(skip_serializing_if = "Option::is_none")]
101    folder_token: Option<String>,
102    #[serde(skip_serializing_if = "Option::is_none")]
103    time_zone: Option<String>,
104}
105
106#[derive(Deserialize, Debug)]
107pub struct CreateAppResponse {
108    /// 多维表格的 app 信息
109    pub app: CreateAppResponseData,
110}
111
112#[derive(Deserialize, Debug)]
113pub struct CreateAppResponseData {
114    /// 多维表格的 app_token
115    pub app_token: String,
116    /// 多维表格的名字
117    pub name: String,
118    /// 多维表格的版本号
119    pub revision: i32,
120    /// 多维表格的链接
121    pub url: String,
122}
123
124impl ApiResponseTrait for CreateAppResponse {
125    fn data_format() -> ResponseFormat {
126        ResponseFormat::Data
127    }
128}
129
130#[cfg(test)]
131mod tests {
132    use super::*;
133    use serde_json::json;
134
135    #[test]
136    fn test_create_app_request() {
137        let request = CreateAppRequest::builder()
138            .name("测试多维表格")
139            .folder_token("fldcnmBA*****yGehy8")
140            .time_zone("Asia/Shanghai")
141            .build();
142
143        assert_eq!(request.name, "测试多维表格");
144        assert_eq!(
145            request.folder_token,
146            Some("fldcnmBA*****yGehy8".to_string())
147        );
148        assert_eq!(request.time_zone, Some("Asia/Shanghai".to_string()));
149    }
150
151    #[test]
152    fn test_create_app_request_body_serialization() {
153        let body = CreateAppRequestBody {
154            name: "测试多维表格".to_string(),
155            folder_token: Some("fldcnmBA*****yGehy8".to_string()),
156            time_zone: Some("Asia/Shanghai".to_string()),
157        };
158
159        let serialized = serde_json::to_value(&body).unwrap();
160        let expected = json!({
161            "name": "测试多维表格",
162            "folder_token": "fldcnmBA*****yGehy8",
163            "time_zone": "Asia/Shanghai"
164        });
165
166        assert_eq!(serialized, expected);
167    }
168}