1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use crate::error::Error;
use crate::model::File;
use crate::request::Endpoint;
use crate::request::Request;
use crate::result::Result;
use crate::util::error_for_lexoffice;
use crate::util::to_json_response;
use reqwest::multipart::{Form, Part};
use reqwest::Method;
use reqwest::Response;
use reqwest::Url;
use serde::Deserialize;
use std::borrow::Cow;
use uuid::Uuid;
impl Endpoint for Request<File> {
const ENDPOINT: &'static str = "files";
}
#[derive(Deserialize, Debug)]
struct FileResponse {
pub id: Uuid,
}
impl Request<File> {
pub fn by_id_url<I>(&self, uuid: I) -> Result<Url>
where
I: Into<Uuid> + Send + Sync,
{
let uuid: Uuid = uuid.into();
let mut url = self.url();
url.path_segments_mut()
.map_err(|_| Error::UrlCannotBeBase)?
.push(&uuid.to_string());
Ok(url)
}
pub async fn by_id_str(self, uuid: &str) -> Result<Response> {
self.by_id(Uuid::parse_str(uuid)?).await
}
pub async fn by_id<I>(self, uuid: I) -> Result<Response>
where
I: Into<Uuid> + Send + Sync,
{
let uuid: Uuid = uuid.into();
let url = self.by_id_url(uuid)?;
error_for_lexoffice(
self.client.http_builder(Method::GET, url).send().await?,
)
.await
}
pub async fn upload<P>(self, file_part: P) -> Result<Uuid>
where
P: Into<Part> + Send + Sync,
{
let file_part = file_part.into();
let url = self.url();
let form = Form::new().part("file", file_part).text("type", "voucher");
to_json_response::<FileResponse>(
self.client()
.http_builder(Method::POST, url)
.multipart(form),
)
.await
.map(|x| x.id)
}
pub async fn upload_bytes<B>(
self,
mime: &'static mime::Mime,
bytes: B,
) -> Result<Uuid>
where
B: Into<Cow<'static, [u8]>>,
{
let file_part = Part::bytes(bytes).mime_str(mime.as_ref())?;
self.upload(file_part).await
}
#[cfg(feature = "fs")]
pub async fn upload_path<P>(self, path: P) -> Result<Uuid>
where
P: AsRef<std::path::Path> + Send + Sync,
{
use crate::mime::*;
use reqwest::Body;
let path = path.as_ref();
let file = tokio::fs::File::open(path).await?;
let stream = crate::fs::BytesStream::new(file);
let mime = path.mime();
let part = Part::stream(Body::wrap_stream(stream))
.mime_str(mime.as_ref())?
.file_name(format!("document.{}", mime.extension()));
self.upload(part).await
}
}