1use crate::Error;
2use crate::FileInfo;
3use crate::FileUpload;
4use crate::ListUserFilesResponse;
5use crate::UploadFileResponse;
6use base64::prelude::*;
7use reqwest::header::AUTHORIZATION;
8use std::sync::Arc;
9
10#[derive(Debug)]
11struct ClientState {
12 token: Option<String>,
13}
14
15#[derive(Debug, Clone)]
17pub struct Client {
18 client: reqwest::Client,
19 state: Arc<std::sync::Mutex<ClientState>>,
20}
21
22impl Client {
23 pub fn new() -> Self {
25 Self {
26 client: reqwest::Client::new(),
27 state: Arc::new(std::sync::Mutex::new(ClientState { token: None })),
28 }
29 }
30
31 pub fn set_token(&self, token: &str) {
33 let token = format!(":{token}");
34 let mut encoded_token =
35 String::with_capacity(base64::encoded_len(token.len(), true).unwrap_or(0));
36 BASE64_STANDARD.encode_string(token, &mut encoded_token);
37
38 self.state.lock().expect("state poisoned").token = Some(encoded_token);
39 }
40
41 pub fn try_get_token(&self) -> Option<String> {
43 self.state.lock().expect("state poisoned").token.clone()
44 }
45
46 pub fn get_token(&self) -> Result<String, Error> {
48 self.try_get_token().ok_or(Error::MissingToken)
49 }
50
51 pub async fn list_user_files(&self) -> Result<ListUserFilesResponse, Error> {
55 let token = self.get_token()?;
56 let response = self
57 .client
58 .get("https://pixeldrain.com/api/user/files")
59 .header(AUTHORIZATION, format!("Basic {token}"))
60 .send()
61 .await?
62 .error_for_status()?;
63
64 let value: ListUserFilesResponse = response.json().await?;
65
66 Ok(value)
67 }
68
69 pub async fn upload_file(&self, file: FileUpload) -> Result<UploadFileResponse, Error> {
73 let token = self.get_token()?;
74
75 let response = self
76 .client
77 .put(format!(
78 "https://pixeldrain.com/api/file/{}",
79 file.file_name
80 ))
81 .header(AUTHORIZATION, format!("Basic {token}"))
82 .body(file.body)
83 .send()
84 .await?
85 .error_for_status()?;
86
87 let value: UploadFileResponse = response.json().await?;
88
89 Ok(value)
90 }
91
92 pub async fn get_file_info(&self, id: &str) -> Result<FileInfo, Error> {
96 let token = self.try_get_token();
97
98 let mut request = self
99 .client
100 .get(format!("https://pixeldrain.com/api/file/{id}/info"));
101 if let Some(token) = token {
102 request = request.header(AUTHORIZATION, format!("Basic {token}"));
103 }
104 let response = request.send().await?.error_for_status()?;
105 let value: FileInfo = response.json().await?;
106
107 Ok(value)
108 }
109
110 pub async fn download_file(&self, id: &str) -> Result<reqwest::Response, Error> {
114 let token = self.try_get_token();
115
116 let mut request = self
117 .client
118 .get(format!("https://pixeldrain.com/api/file/{id}"));
119 if let Some(token) = token {
120 request = request.header(AUTHORIZATION, format!("Basic {token}"));
121 }
122 let response = request.send().await?.error_for_status()?;
123
124 Ok(response)
125 }
126}
127
128impl Default for Client {
129 fn default() -> Self {
130 Self::new()
131 }
132}