open_lark/service/im/v1/file/
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 FileService {
20    pub config: Config,
21}
22
23/// 上传文件响应
24#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct CreateFileResponse {
26    /// 文件的key
27    pub file_key: String,
28}
29
30impl ApiResponseTrait for CreateFileResponse {
31    fn data_format() -> ResponseFormat {
32        ResponseFormat::Data
33    }
34}
35
36/// 下载文件响应
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct GetFileResponse {
39    /// 文件数据
40    pub data: Vec<u8>,
41}
42
43impl ApiResponseTrait for GetFileResponse {
44    fn data_format() -> ResponseFormat {
45        ResponseFormat::Data
46    }
47}
48
49impl FileService {
50    pub fn new(config: Config) -> Self {
51        Self { config }
52    }
53
54    /// 上传文件
55    pub async fn create(
56        &self,
57        file_type: &str,
58        file_name: &str,
59        file_data: Vec<u8>,
60        option: Option<RequestOption>,
61    ) -> SDKResult<CreateFileResponse> {
62        let mut query_params = HashMap::new();
63        query_params.insert("file_type".to_string(), file_type.to_string());
64        query_params.insert("file_name".to_string(), file_name.to_string());
65
66        let api_req = ApiRequest {
67            http_method: Method::POST,
68            api_path: "/open-apis/im/v1/files".to_string(),
69            supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
70            query_params,
71            body: file_data,
72            ..Default::default()
73        };
74
75        let api_resp: BaseResponse<CreateFileResponse> =
76            Transport::request(api_req, &self.config, option).await?;
77        api_resp.into_result()
78    }
79
80    /// 下载文件
81    pub async fn get(
82        &self,
83        file_key: &str,
84        option: Option<RequestOption>,
85    ) -> SDKResult<GetFileResponse> {
86        let api_req = ApiRequest {
87            http_method: Method::GET,
88            api_path: format!("/open-apis/im/v1/files/{file_key}"),
89            supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
90            ..Default::default()
91        };
92
93        let api_resp: BaseResponse<GetFileResponse> =
94            Transport::request(api_req, &self.config, option).await?;
95        api_resp.into_result()
96    }
97
98    /// 创建文件上传Builder (推荐)
99    pub fn upload_builder(&self) -> FileUploadBuilder {
100        FileUploadBuilder::new()
101    }
102
103    /// 创建文件下载Builder (推荐)  
104    pub fn download_builder(&self) -> FileDownloadBuilder {
105        FileDownloadBuilder::new()
106    }
107}
108
109/// 文件上传Builder
110#[derive(Default)]
111pub struct FileUploadBuilder {
112    file_type: Option<String>,
113    file_name: Option<String>,
114    file_data: Option<Vec<u8>>,
115}
116
117impl FileUploadBuilder {
118    pub fn new() -> Self {
119        Self::default()
120    }
121
122    /// 设置文件类型
123    pub fn file_type(mut self, file_type: impl ToString) -> Self {
124        self.file_type = Some(file_type.to_string());
125        self
126    }
127
128    /// 设置文件名
129    pub fn file_name(mut self, file_name: impl ToString) -> Self {
130        self.file_name = Some(file_name.to_string());
131        self
132    }
133
134    /// 设置文件数据
135    pub fn file_data(mut self, file_data: Vec<u8>) -> Self {
136        self.file_data = Some(file_data);
137        self
138    }
139
140    pub fn build(self) -> (String, String, Vec<u8>) {
141        (
142            self.file_type.unwrap_or_default(),
143            self.file_name.unwrap_or_default(),
144            self.file_data.unwrap_or_default(),
145        )
146    }
147}
148
149#[async_trait]
150impl ExecutableBuilder<FileService, (String, String, Vec<u8>), CreateFileResponse>
151    for FileUploadBuilder
152{
153    fn build(self) -> (String, String, Vec<u8>) {
154        self.build()
155    }
156
157    async fn execute(self, service: &FileService) -> SDKResult<CreateFileResponse> {
158        let (file_type, file_name, file_data) = self.build();
159        service
160            .create(&file_type, &file_name, file_data, None)
161            .await
162    }
163
164    async fn execute_with_options(
165        self,
166        service: &FileService,
167        option: RequestOption,
168    ) -> SDKResult<CreateFileResponse> {
169        let (file_type, file_name, file_data) = self.build();
170        service
171            .create(&file_type, &file_name, file_data, Some(option))
172            .await
173    }
174}
175
176/// 文件下载Builder  
177#[derive(Default)]
178pub struct FileDownloadBuilder {
179    file_key: Option<String>,
180}
181
182impl FileDownloadBuilder {
183    pub fn new() -> Self {
184        Self::default()
185    }
186
187    /// 设置文件key
188    pub fn file_key(mut self, file_key: impl ToString) -> Self {
189        self.file_key = Some(file_key.to_string());
190        self
191    }
192
193    pub fn build(self) -> String {
194        self.file_key.unwrap_or_default()
195    }
196}
197
198#[async_trait]
199impl ExecutableBuilder<FileService, String, GetFileResponse> for FileDownloadBuilder {
200    fn build(self) -> String {
201        self.build()
202    }
203
204    async fn execute(self, service: &FileService) -> SDKResult<GetFileResponse> {
205        let file_key = self.build();
206        service.get(&file_key, None).await
207    }
208
209    async fn execute_with_options(
210        self,
211        service: &FileService,
212        option: RequestOption,
213    ) -> SDKResult<GetFileResponse> {
214        let file_key = self.build();
215        service.get(&file_key, Some(option)).await
216    }
217}