1use crate::Error;
4use log::debug;
5use serde::Serialize;
6
7pub mod dav;
9pub mod file;
11pub mod models;
13pub mod session;
15pub mod share;
17pub mod site;
19pub mod uri;
21pub mod user;
23pub mod workflow;
25
26#[derive(Debug, Clone)]
28pub struct ApiV4Client {
29 pub base_url: String,
31 pub http_client: reqwest::Client,
33 pub token: Option<String>,
35}
36
37impl ApiV4Client {
38 pub fn new(base_url: &str) -> Self {
40 Self {
41 base_url: base_url.to_string(),
42 http_client: reqwest::Client::new(),
43 token: None,
44 }
45 }
46
47 pub fn set_token(&mut self, token: String) {
49 self.token = Some(token);
50 }
51
52 pub fn clear_token(&mut self) {
54 self.token = None;
55 }
56
57 fn get_url(&self, endpoint: &str) -> String {
59 format!(
60 "{}/api/v4/{}",
61 self.base_url.trim_end_matches('/'),
62 endpoint.trim_start_matches('/')
63 )
64 }
65
66 pub async fn get<T>(&self, endpoint: &str) -> Result<T, Error>
68 where
69 T: serde::de::DeserializeOwned + std::fmt::Debug,
70 {
71 let url = self.get_url(endpoint);
72 let mut request = self.http_client.get(&url);
73
74 if let Some(token) = &self.token {
75 request = request.bearer_auth(token);
76 }
77 debug!("GET URL: {}", url);
78
79 let response = request.send().await?;
80 let status = response.status();
81
82 if !status.is_success() {
84 let raw_text = response.text().await?;
85 if let Ok(api_response) =
87 serde_json::from_str::<crate::ApiResponse<serde_json::Value>>(&raw_text)
88 && api_response.code != 0
89 {
90 return Err(Error::Api {
91 code: api_response.code,
92 message: api_response.msg,
93 });
94 }
95 return Err(Error::Api {
97 code: status.as_u16() as i32,
98 message: raw_text.trim().to_string(),
99 });
100 }
101
102 let raw_text = response.text().await?;
104
105 match serde_json::from_str::<T>(&raw_text) {
106 Ok(json) => {
107 debug!("Response status: {}, JSON: {:?}", status, json);
108 Ok(json)
109 }
110 Err(e) => {
111 debug!("JSON parse error: {}, raw response: {}", e, raw_text);
112 Err(Error::Json(e))
113 }
114 }
115 }
116
117 pub async fn post<T>(&self, endpoint: &str, body: &impl Serialize) -> Result<T, Error>
119 where
120 T: serde::de::DeserializeOwned + std::fmt::Debug,
121 {
122 let url = self.get_url(endpoint);
123 let mut request = self.http_client.post(&url).json(body);
124
125 if let Some(token) = &self.token {
126 request = request.bearer_auth(token);
127 }
128
129 debug!("POST URL: {}", url);
130
131 if let Ok(json_str) = serde_json::to_string(body) {
133 debug!("Request body: {}", json_str);
134 }
135
136 let response = request.send().await?;
137 let status = response.status();
138
139 if !status.is_success() {
141 let raw_text = response.text().await?;
142 if let Ok(api_response) =
143 serde_json::from_str::<crate::ApiResponse<serde_json::Value>>(&raw_text)
144 && api_response.code != 0
145 {
146 return Err(Error::Api {
147 code: api_response.code,
148 message: api_response.msg,
149 });
150 }
151 return Err(Error::Api {
152 code: status.as_u16() as i32,
153 message: raw_text.trim().to_string(),
154 });
155 }
156
157 let raw_text = response.text().await?;
158
159 match serde_json::from_str::<T>(&raw_text) {
160 Ok(json) => {
161 debug!("Response status: {}, JSON: {:?}", status, json);
162 Ok(json)
163 }
164 Err(e) => {
165 debug!("JSON parse error: {}, raw response: {}", e, raw_text);
166 Err(Error::Json(e))
167 }
168 }
169 }
170
171 pub async fn put<T>(&self, endpoint: &str, body: &impl Serialize) -> Result<T, Error>
173 where
174 T: serde::de::DeserializeOwned + std::fmt::Debug,
175 {
176 let url = self.get_url(endpoint);
177 let mut request = self.http_client.put(&url).json(body);
178
179 if let Some(token) = &self.token {
180 request = request.bearer_auth(token);
181 }
182 debug!("PUT URL: {}", url);
183
184 let response = request.send().await?;
185 let status = response.status();
186
187 if !status.is_success() {
189 let raw_text = response.text().await?;
190 if let Ok(api_response) =
191 serde_json::from_str::<crate::ApiResponse<serde_json::Value>>(&raw_text)
192 && api_response.code != 0
193 {
194 return Err(Error::Api {
195 code: api_response.code,
196 message: api_response.msg,
197 });
198 }
199 return Err(Error::Api {
200 code: status.as_u16() as i32,
201 message: raw_text.trim().to_string(),
202 });
203 }
204
205 let raw_text = response.text().await?;
206
207 match serde_json::from_str::<T>(&raw_text) {
208 Ok(json) => {
209 debug!("Response status: {}, JSON: {:?}", status, json);
210 Ok(json)
211 }
212 Err(e) => {
213 debug!("JSON parse error: {}, raw response: {}", e, raw_text);
214 Err(Error::Json(e))
215 }
216 }
217 }
218
219 pub async fn patch<T>(&self, endpoint: &str, body: &impl Serialize) -> Result<T, Error>
220 where
221 T: serde::de::DeserializeOwned + std::fmt::Debug,
222 {
223 let url = self.get_url(endpoint);
224 let mut request = self.http_client.patch(&url).json(body);
225
226 if let Some(token) = &self.token {
227 request = request.bearer_auth(token);
228 }
229 debug!("PATCH URL: {}", url);
230
231 let response = request.send().await?;
232 let status = response.status();
233
234 if !status.is_success() {
236 let raw_text = response.text().await?;
237 if let Ok(api_response) =
238 serde_json::from_str::<crate::ApiResponse<serde_json::Value>>(&raw_text)
239 && api_response.code != 0
240 {
241 return Err(Error::Api {
242 code: api_response.code,
243 message: api_response.msg,
244 });
245 }
246 return Err(Error::Api {
247 code: status.as_u16() as i32,
248 message: raw_text.trim().to_string(),
249 });
250 }
251
252 let raw_text = response.text().await?;
253
254 match serde_json::from_str::<T>(&raw_text) {
255 Ok(json) => {
256 debug!("Response status: {}, JSON: {:?}", status, json);
257 Ok(json)
258 }
259 Err(e) => {
260 debug!("JSON parse error: {}, raw response: {}", e, raw_text);
261 Err(Error::Json(e))
262 }
263 }
264 }
265
266 pub async fn delete<T>(&self, endpoint: &str) -> Result<T, Error>
268 where
269 T: serde::de::DeserializeOwned + std::fmt::Debug,
270 {
271 let url = self.get_url(endpoint);
272 let mut request = self.http_client.delete(&url);
273
274 if let Some(token) = &self.token {
275 request = request.bearer_auth(token);
276 }
277 debug!("DELETE URL: {}", url);
278
279 let response = request.send().await?;
280 let status = response.status();
281
282 if !status.is_success() {
284 let raw_text = response.text().await?;
285 if let Ok(api_response) =
286 serde_json::from_str::<crate::ApiResponse<serde_json::Value>>(&raw_text)
287 && api_response.code != 0
288 {
289 return Err(Error::Api {
290 code: api_response.code,
291 message: api_response.msg,
292 });
293 }
294 return Err(Error::Api {
295 code: status.as_u16() as i32,
296 message: raw_text.trim().to_string(),
297 });
298 }
299
300 let raw_text = response.text().await?;
301
302 match serde_json::from_str::<T>(&raw_text) {
303 Ok(json) => {
304 debug!("Response status: {}, JSON: {:?}", status, json);
305 Ok(json)
306 }
307 Err(e) => {
308 debug!("JSON parse error: {}, raw response: {}", e, raw_text);
309 Err(Error::Json(e))
310 }
311 }
312 }
313
314 pub async fn delete_with_body<T>(
316 &self,
317 endpoint: &str,
318 body: &impl Serialize,
319 ) -> Result<T, Error>
320 where
321 T: serde::de::DeserializeOwned + std::fmt::Debug,
322 {
323 let url = self.get_url(endpoint);
324 let mut request = self.http_client.delete(&url).json(body);
325
326 if let Some(token) = &self.token {
327 request = request.bearer_auth(token);
328 }
329 debug!("DELETE URL: {} with body", url);
330
331 let response = request.send().await?;
332 let status = response.status();
333
334 if !status.is_success() {
336 let raw_text = response.text().await?;
337 if let Ok(api_response) =
338 serde_json::from_str::<crate::ApiResponse<serde_json::Value>>(&raw_text)
339 && api_response.code != 0
340 {
341 return Err(Error::Api {
342 code: api_response.code,
343 message: api_response.msg,
344 });
345 }
346 return Err(Error::Api {
347 code: status.as_u16() as i32,
348 message: raw_text.trim().to_string(),
349 });
350 }
351
352 let raw_text = response.text().await?;
353
354 match serde_json::from_str::<T>(&raw_text) {
355 Ok(json) => {
356 debug!("Response status: {}, JSON: {:?}", status, json);
357 Ok(json)
358 }
359 Err(e) => {
360 debug!("JSON parse error: {}, raw response: {}", e, raw_text);
361 Err(Error::Json(e))
362 }
363 }
364 }
365}