open_lark/service/im/v1/image/
mod.rs

1use reqwest::Method;
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5use crate::core::{
6    api_req::ApiRequest,
7    api_resp::{ApiResponseTrait, BaseResponse, ResponseFormat},
8    config::Config,
9    constants::AccessTokenType,
10    http::Transport,
11    req_option::RequestOption,
12    standard_response::StandardResponse,
13    trait_system::executable_builder::ExecutableBuilder,
14    SDKResult,
15};
16use async_trait::async_trait;
17
18/// 图片服务
19pub struct ImageService {
20    pub config: Config,
21}
22
23/// 上传图片响应
24#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct CreateImageResponse {
26    /// 图片的key
27    pub image_key: String,
28}
29
30impl ApiResponseTrait for CreateImageResponse {
31    fn data_format() -> ResponseFormat {
32        ResponseFormat::Data
33    }
34}
35
36/// 下载图片响应
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct GetImageResponse {
39    /// 图片数据
40    pub data: Vec<u8>,
41}
42
43impl ApiResponseTrait for GetImageResponse {
44    fn data_format() -> ResponseFormat {
45        ResponseFormat::Data
46    }
47}
48
49impl ImageService {
50    pub fn new(config: Config) -> Self {
51        Self { config }
52    }
53
54    /// 上传图片
55    pub async fn create(
56        &self,
57        image_type: &str,
58        image_data: Vec<u8>,
59        option: Option<RequestOption>,
60    ) -> SDKResult<CreateImageResponse> {
61        let api_req = ApiRequest {
62            http_method: Method::POST,
63            api_path: "/open-apis/im/v1/images".to_string(),
64            supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
65            query_params: HashMap::from([("image_type".to_string(), image_type.to_string())]),
66            body: image_data,
67            ..Default::default()
68        };
69
70        let api_resp: BaseResponse<CreateImageResponse> =
71            Transport::request(api_req, &self.config, option).await?;
72        api_resp.into_result()
73    }
74
75    /// 下载图片  
76    pub async fn get(
77        &self,
78        image_key: &str,
79        option: Option<RequestOption>,
80    ) -> SDKResult<GetImageResponse> {
81        let api_req = ApiRequest {
82            http_method: Method::GET,
83            api_path: format!("/open-apis/im/v1/images/{image_key}"),
84            supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
85            ..Default::default()
86        };
87
88        let api_resp: BaseResponse<GetImageResponse> =
89            Transport::request(api_req, &self.config, option).await?;
90        api_resp.into_result()
91    }
92
93    /// 创建图片上传Builder (推荐)
94    pub fn upload_builder(&self) -> ImageUploadBuilder {
95        ImageUploadBuilder::new()
96    }
97
98    /// 创建图片下载Builder (推荐)
99    pub fn download_builder(&self) -> ImageDownloadBuilder {
100        ImageDownloadBuilder::new()
101    }
102}
103
104/// 图片上传Builder
105#[derive(Default)]
106pub struct ImageUploadBuilder {
107    image_type: Option<String>,
108    image_data: Option<Vec<u8>>,
109}
110
111impl ImageUploadBuilder {
112    pub fn new() -> Self {
113        Self::default()
114    }
115
116    /// 设置图片类型
117    pub fn image_type(mut self, image_type: impl ToString) -> Self {
118        self.image_type = Some(image_type.to_string());
119        self
120    }
121
122    /// 设置图片数据
123    pub fn image_data(mut self, image_data: Vec<u8>) -> Self {
124        self.image_data = Some(image_data);
125        self
126    }
127
128    pub fn build(self) -> (String, Vec<u8>) {
129        (
130            self.image_type.unwrap_or_default(),
131            self.image_data.unwrap_or_default(),
132        )
133    }
134}
135
136#[async_trait]
137impl ExecutableBuilder<ImageService, (String, Vec<u8>), CreateImageResponse>
138    for ImageUploadBuilder
139{
140    fn build(self) -> (String, Vec<u8>) {
141        self.build()
142    }
143
144    async fn execute(self, service: &ImageService) -> SDKResult<CreateImageResponse> {
145        let (image_type, image_data) = self.build();
146        service.create(&image_type, image_data, None).await
147    }
148
149    async fn execute_with_options(
150        self,
151        service: &ImageService,
152        option: RequestOption,
153    ) -> SDKResult<CreateImageResponse> {
154        let (image_type, image_data) = self.build();
155        service.create(&image_type, image_data, Some(option)).await
156    }
157}
158
159/// 图片下载Builder
160#[derive(Default)]
161pub struct ImageDownloadBuilder {
162    image_key: Option<String>,
163}
164
165impl ImageDownloadBuilder {
166    pub fn new() -> Self {
167        Self::default()
168    }
169
170    /// 设置图片key
171    pub fn image_key(mut self, image_key: impl ToString) -> Self {
172        self.image_key = Some(image_key.to_string());
173        self
174    }
175
176    pub fn build(self) -> String {
177        self.image_key.unwrap_or_default()
178    }
179}
180
181#[async_trait]
182impl ExecutableBuilder<ImageService, String, GetImageResponse> for ImageDownloadBuilder {
183    fn build(self) -> String {
184        self.build()
185    }
186
187    async fn execute(self, service: &ImageService) -> SDKResult<GetImageResponse> {
188        let image_key = self.build();
189        service.get(&image_key, None).await
190    }
191
192    async fn execute_with_options(
193        self,
194        service: &ImageService,
195        option: RequestOption,
196    ) -> SDKResult<GetImageResponse> {
197        let image_key = self.build();
198        service.get(&image_key, Some(option)).await
199    }
200}