1mod client;
2mod model;
3
4pub use self::client::Client;
5pub use self::model::FileInfo;
6pub use self::model::ListUserFilesResponse;
7pub use self::model::UploadFileResponse;
8pub use reqwest::Body;
9use std::path::Path;
10use tokio_util::io::ReaderStream;
11
12#[derive(Debug)]
14pub struct FileUpload {
15 pub file_name: String,
17
18 pub body: Body,
20}
21
22impl FileUpload {
23 pub async fn from_path<P>(path: P) -> std::io::Result<Self>
24 where
25 P: AsRef<Path>,
26 {
27 let path = path.as_ref();
28
29 let file_name = path
30 .file_name()
31 .and_then(|value| value.to_str())
32 .ok_or_else(|| std::io::Error::other("Missing file name"))?
33 .to_string();
34
35 let file = tokio::fs::File::open(path).await?;
36 let body = reqwest::Body::from(file);
37
38 Ok(Self { file_name, body })
39 }
40
41 pub fn from_async_read<R>(file_name: String, reader: R) -> Self
42 where
43 R: tokio::io::AsyncRead + Send + 'static,
44 {
45 Self {
46 file_name,
47 body: reqwest::Body::wrap_stream(ReaderStream::new(reader)),
48 }
49 }
50}
51
52#[derive(Debug, thiserror::Error)]
54pub enum Error {
55 #[error("http error")]
56 Reqwest(#[from] reqwest::Error),
57
58 #[error("missing token")]
59 MissingToken,
60}
61
62#[cfg(test)]
63mod test {
64 use super::*;
65 use std::path::Path;
66 use std::sync::LazyLock;
67
68 fn try_read_to_string<P>(path: P) -> std::io::Result<Option<String>>
69 where
70 P: AsRef<Path>,
71 {
72 match std::fs::read_to_string(path) {
73 Ok(value) => Ok(Some(value)),
74 Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(None),
75 Err(error) => Err(error),
76 }
77 }
78
79 fn load_token() -> String {
80 if let Some(token) = try_read_to_string("token.txt").expect("failed to load token.txt") {
81 return token;
82 }
83
84 std::env::var("PIXELDRAIN_RS_TOKEN")
85 .expect("missing `PIXELDRAIN_RS_TOKEN` environment variable")
86 }
87
88 static TOKEN: LazyLock<String> = LazyLock::new(load_token);
89
90 #[tokio::test]
91 async fn user_list_works() {
92 let client = Client::new();
93 client.set_token(&TOKEN);
94
95 let response = client.list_user_files().await.expect("failed to list");
96 dbg!(response);
97 }
98}