jmap_client/blob/
upload.rs1use reqwest::header::CONTENT_TYPE;
13use serde::Deserialize;
14
15use crate::{client::Client, core::session::URLPart};
16
17#[cfg(feature = "blocking")]
18use reqwest::blocking::Client as HttpClient;
19#[cfg(feature = "async")]
20use reqwest::Client as HttpClient;
21
22#[derive(Debug, Deserialize)]
23pub struct UploadResponse {
24 #[serde(rename = "accountId")]
25 account_id: String,
26
27 #[serde(rename = "blobId")]
28 blob_id: String,
29
30 #[serde(rename = "type")]
31 type_: String,
32
33 #[serde(rename = "size")]
34 size: usize,
35}
36
37impl Client {
38 #[maybe_async::maybe_async]
39 pub async fn upload(
40 &self,
41 account_id: Option<&str>,
42 blob: Vec<u8>,
43 content_type: Option<&str>,
44 ) -> crate::Result<UploadResponse> {
45 let account_id = account_id.unwrap_or_else(|| self.default_account_id());
46 let mut upload_url =
47 String::with_capacity(self.session().upload_url().len() + account_id.len());
48
49 for part in self.upload_url() {
50 match part {
51 URLPart::Value(value) => {
52 upload_url.push_str(value);
53 }
54 URLPart::Parameter(param) => {
55 if let super::URLParameter::AccountId = param {
56 upload_url.push_str(account_id);
57 }
58 }
59 }
60 }
61
62 serde_json::from_slice::<UploadResponse>(
63 &Client::handle_error(
64 HttpClient::builder()
65 .timeout(self.timeout())
66 .danger_accept_invalid_certs(self.accept_invalid_certs)
67 .redirect(self.redirect_policy())
68 .default_headers(self.headers().clone())
69 .build()?
70 .post(upload_url)
71 .header(
72 CONTENT_TYPE,
73 content_type.unwrap_or("application/octet-stream"),
74 )
75 .body(blob)
76 .send()
77 .await?,
78 )
79 .await?
80 .bytes()
81 .await?,
82 )
83 .map_err(|err| err.into())
84 }
85}
86
87impl UploadResponse {
88 pub fn account_id(&self) -> &str {
89 &self.account_id
90 }
91
92 pub fn blob_id(&self) -> &str {
93 &self.blob_id
94 }
95
96 pub fn content_type(&self) -> &str {
97 &self.type_
98 }
99
100 pub fn size(&self) -> usize {
101 self.size
102 }
103
104 pub fn take_blob_id(&mut self) -> String {
105 std::mem::take(&mut self.blob_id)
106 }
107}