open_lark/service/cloud_docs/sheets/v3/data_operation/
append_data.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    service::sheets::v3::DataOperationService,
15};
16
17impl DataOperationService {
18    /// 追加数据
19    ///
20    /// <https://open.feishu.cn/document/ukTMukTMukTM/uUDN04SN0QjL1QDN/sheets-v3/spreadsheet-value/append>
21    pub async fn append_data(
22        &self,
23        request: AppendDataRequest,
24        option: Option<RequestOption>,
25    ) -> SDKResult<BaseResponse<AppendDataResponseData>> {
26        let mut api_req = request.api_request;
27        api_req.http_method = Method::POST;
28        api_req.api_path = format!(
29            "/open-apis/sheets/v3/spreadsheets/{}/values/{}/append",
30            request.spreadsheet_token, request.range
31        );
32        api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
33
34        let api_resp = Transport::request(api_req, &self.config, option).await?;
35
36        Ok(api_resp)
37    }
38}
39
40/// 追加数据请求
41#[derive(Default, Debug, Serialize, Deserialize)]
42pub struct AppendDataRequest {
43    #[serde(skip)]
44    api_request: ApiRequest,
45    /// spreadsheet 的 token
46    spreadsheet_token: String,
47    /// 查询范围,包含 sheetId 与单元格范围两部分
48    range: String,
49    /// 插入数据的方式
50    #[serde(rename = "insertDataOption")]
51    insert_data_option: Option<String>,
52    /// 数据值
53    #[serde(rename = "valueRange")]
54    value_range: ValueRangeRequest,
55}
56
57impl AppendDataRequest {
58    pub fn builder() -> AppendDataRequestBuilder {
59        AppendDataRequestBuilder::default()
60    }
61}
62
63#[derive(Default)]
64pub struct AppendDataRequestBuilder {
65    request: AppendDataRequest,
66}
67
68impl AppendDataRequestBuilder {
69    pub fn spreadsheet_token(mut self, spreadsheet_token: impl ToString) -> Self {
70        self.request.spreadsheet_token = spreadsheet_token.to_string();
71        self
72    }
73
74    pub fn range(mut self, range: impl ToString) -> Self {
75        self.request.range = range.to_string();
76        self
77    }
78
79    pub fn insert_data_option(mut self, insert_data_option: impl ToString) -> Self {
80        self.request.insert_data_option = Some(insert_data_option.to_string());
81        self
82    }
83
84    pub fn values(mut self, values: Vec<Vec<serde_json::Value>>) -> Self {
85        self.request.value_range = ValueRangeRequest {
86            range: self.request.range.clone(),
87            values,
88        };
89        self
90    }
91
92    pub fn build(mut self) -> AppendDataRequest {
93        self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
94        self.request
95    }
96}
97
98// Trait implementation
99impl_executable_builder_owned!(
100    AppendDataRequestBuilder,
101    DataOperationService,
102    AppendDataRequest,
103    BaseResponse<AppendDataResponseData>,
104    append_data
105);
106
107/// 值与范围请求
108#[derive(Default, Debug, Serialize, Deserialize)]
109pub struct ValueRangeRequest {
110    /// 查询范围
111    pub range: String,
112    /// 范围内的值
113    pub values: Vec<Vec<serde_json::Value>>,
114}
115
116/// 追加数据响应体最外层
117#[derive(Deserialize, Debug)]
118pub struct AppendDataResponseData {
119    /// 表格的 token
120    #[serde(rename = "spreadsheetToken")]
121    pub spreadsheet_token: String,
122    /// 数据更新的位置
123    #[serde(rename = "tableRange")]
124    pub table_range: String,
125    /// sheet 的版本号
126    pub revision: i32,
127    /// 更新的行数
128    pub updates: UpdatesInfo,
129}
130
131impl ApiResponseTrait for AppendDataResponseData {
132    fn data_format() -> ResponseFormat {
133        ResponseFormat::Data
134    }
135}
136
137/// 更新信息
138#[derive(Deserialize, Debug)]
139pub struct UpdatesInfo {
140    /// 受更新影响的表格范围
141    #[serde(rename = "updatedRange")]
142    pub updated_range: String,
143    /// 更新的行数
144    #[serde(rename = "updatedRows")]
145    pub updated_rows: i32,
146    /// 更新的列数
147    #[serde(rename = "updatedColumns")]
148    pub updated_columns: i32,
149    /// 更新的单元格数
150    #[serde(rename = "updatedCells")]
151    pub updated_cells: i32,
152}
153
154#[cfg(test)]
155mod test {
156    use serde_json::json;
157
158    use super::AppendDataResponseData;
159
160    #[test]
161    fn test_append_data_response() {
162        let json = json!({
163            "spreadsheetToken": "shtcnmBA*****yGehy8",
164            "tableRange": "Sheet1!A1:B2",
165            "revision": 123,
166            "updates": {
167                "updatedRange": "Sheet1!A3:B3",
168                "updatedRows": 1,
169                "updatedColumns": 2,
170                "updatedCells": 2
171            }
172        });
173
174        let response: AppendDataResponseData = serde_json::from_value(json).unwrap();
175        assert_eq!(response.spreadsheet_token, "shtcnmBA*****yGehy8");
176        assert_eq!(response.updates.updated_rows, 1);
177    }
178}