open_lark/service/im/v1/file/
mod.rs1use 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
18pub struct FileService {
20 pub config: Config,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct CreateFileResponse {
26 pub file_key: String,
28}
29
30impl ApiResponseTrait for CreateFileResponse {
31 fn data_format() -> ResponseFormat {
32 ResponseFormat::Data
33 }
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct GetFileResponse {
39 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 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 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 pub fn upload_builder(&self) -> FileUploadBuilder {
100 FileUploadBuilder::new()
101 }
102
103 pub fn download_builder(&self) -> FileDownloadBuilder {
105 FileDownloadBuilder::new()
106 }
107}
108
109#[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 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 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 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#[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 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}