open_lark/service/cloud_docs/sheets/v3/data_operation/
write_images.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        standard_response::StandardResponse,
13        SDKResult,
14    },
15    impl_executable_builder_owned,
16    service::sheets::v3::DataOperationService,
17};
18
19impl DataOperationService {
20    /// 写入图片
21    pub async fn write_images(
22        &self,
23        request: WriteImagesRequest,
24        option: Option<RequestOption>,
25    ) -> SDKResult<WriteImagesResponseData> {
26        let mut api_req = request.api_request;
27        api_req.http_method = Method::POST;
28        api_req.api_path =
29            SHEETS_V3_SPREADSHEET_VALUES_IMAGE.replace("{}", &request.spreadsheet_token);
30        api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
31
32        let api_resp: BaseResponse<WriteImagesResponseData> =
33            Transport::request(api_req, &self.config, option).await?;
34        api_resp.into_result()
35    }
36}
37
38/// 写入图片请求
39#[derive(Default, Debug, Serialize, Deserialize)]
40pub struct WriteImagesRequest {
41    #[serde(skip)]
42    api_request: ApiRequest,
43    /// spreadsheet 的 token
44    spreadsheet_token: String,
45    /// 图片范围数据
46    #[serde(rename = "valueRange")]
47    value_range: ImageValueRange,
48}
49
50impl WriteImagesRequest {
51    pub fn builder() -> WriteImagesRequestBuilder {
52        WriteImagesRequestBuilder::default()
53    }
54}
55
56#[derive(Default)]
57pub struct WriteImagesRequestBuilder {
58    request: WriteImagesRequest,
59}
60
61impl WriteImagesRequestBuilder {
62    pub fn spreadsheet_token(mut self, spreadsheet_token: impl ToString) -> Self {
63        self.request.spreadsheet_token = spreadsheet_token.to_string();
64        self
65    }
66
67    pub fn range(mut self, range: impl ToString) -> Self {
68        self.request.value_range.range = range.to_string();
69        self
70    }
71
72    pub fn add_image(mut self, image_data: ImageData) -> Self {
73        self.request.value_range.values.push(vec![image_data]);
74        self
75    }
76
77    pub fn images(mut self, images: Vec<Vec<ImageData>>) -> Self {
78        self.request.value_range.values = images;
79        self
80    }
81
82    pub fn build(mut self) -> WriteImagesRequest {
83        self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
84        self.request
85    }
86}
87
88/// 图片值范围
89#[derive(Default, Debug, Serialize, Deserialize)]
90pub struct ImageValueRange {
91    /// 范围
92    pub range: String,
93    /// 图片数据值
94    pub values: Vec<Vec<ImageData>>,
95}
96
97/// 图片数据
98#[derive(Debug, Serialize, Deserialize)]
99pub struct ImageData {
100    /// 图片类型,固定值为 "image"
101    #[serde(rename = "type")]
102    pub data_type: String,
103    /// 图片 token
104    pub image_token: String,
105    /// 图片宽度(像素)
106    pub width: Option<i32>,
107    /// 图片高度(像素)
108    pub height: Option<i32>,
109}
110
111impl ImageData {
112    pub fn new(image_token: impl ToString) -> Self {
113        Self {
114            data_type: "image".to_string(),
115            image_token: image_token.to_string(),
116            width: None,
117            height: None,
118        }
119    }
120
121    pub fn with_size(mut self, width: i32, height: i32) -> Self {
122        self.width = Some(width);
123        self.height = Some(height);
124        self
125    }
126}
127
128/// 写入图片响应体最外层
129#[derive(Deserialize, Debug)]
130pub struct WriteImagesResponseData {
131    /// 表格的 token
132    #[serde(rename = "spreadsheetToken")]
133    pub spreadsheet_token: String,
134    /// 数据更新的位置
135    #[serde(rename = "tableRange")]
136    pub table_range: String,
137    /// sheet 的版本号
138    pub revision: i32,
139    /// 更新信息
140    pub updates: WriteImageUpdatesInfo,
141}
142
143impl ApiResponseTrait for WriteImagesResponseData {
144    fn data_format() -> ResponseFormat {
145        ResponseFormat::Data
146    }
147}
148
149impl_executable_builder_owned!(
150    WriteImagesRequestBuilder,
151    DataOperationService,
152    WriteImagesRequest,
153    WriteImagesResponseData,
154    write_images
155);
156
157/// 更新信息
158#[derive(Deserialize, Debug)]
159pub struct WriteImageUpdatesInfo {
160    /// 受更新影响的表格范围
161    #[serde(rename = "updatedRange")]
162    pub updated_range: String,
163    /// 更新的行数
164    #[serde(rename = "updatedRows")]
165    pub updated_rows: i32,
166    /// 更新的列数
167    #[serde(rename = "updatedColumns")]
168    pub updated_columns: i32,
169    /// 更新的单元格数
170    #[serde(rename = "updatedCells")]
171    pub updated_cells: i32,
172    /// 写入的图片数量
173    #[serde(rename = "updatedImages")]
174    pub updated_images: i32,
175}
176
177#[cfg(test)]
178#[allow(unused_variables, unused_unsafe)]
179mod test {
180    use serde_json::json;
181
182    use super::{ImageData, WriteImagesResponseData};
183
184    #[test]
185    fn test_write_images_response() {
186        let json = json!({
187            "spreadsheetToken": "shtcnmBA*****yGehy8",
188            "tableRange": "Sheet1!A1:B2",
189            "revision": 125,
190            "updates": {
191                "updatedRange": "Sheet1!A1:B2",
192                "updatedRows": 2,
193                "updatedColumns": 2,
194                "updatedCells": 4,
195                "updatedImages": 2
196            }
197        });
198
199        let response: WriteImagesResponseData = serde_json::from_value(json).unwrap();
200        assert_eq!(response.spreadsheet_token, "shtcnmBA*****yGehy8");
201        assert_eq!(response.updates.updated_images, 2);
202    }
203
204    #[test]
205    fn test_image_data_creation() {
206        let image =
207            ImageData::new("img_v2_041b9112-02e8-4c12-b2f2-**********g").with_size(200, 150);
208
209        assert_eq!(image.data_type, "image");
210        assert_eq!(image.width, Some(200));
211        assert_eq!(image.height, Some(150));
212    }
213
214    #[test]
215    fn test_image_data_serialization() {
216        let image = ImageData {
217            data_type: "image".to_string(),
218            image_token: "img_v2_041b9112-02e8-4c12-b2f2-**********g".to_string(),
219            width: Some(100),
220            height: Some(80),
221        };
222
223        let json = serde_json::to_value(&image).unwrap();
224        assert_eq!(json["type"], "image");
225        assert_eq!(
226            json["image_token"],
227            "img_v2_041b9112-02e8-4c12-b2f2-**********g"
228        );
229        assert_eq!(json["width"], 100);
230        assert_eq!(json["height"], 80);
231    }
232}