1
2#[cfg(target_arch = "wasm32")]
3#[derive(Debug, Clone)]
4pub enum ForgeUpload {
5 File(web_sys::File),
6 Blob {
7 blob: web_sys::Blob,
8 file_name: Option<String>,
9 },
10}
11
12#[cfg(target_arch = "wasm32")]
13impl ForgeUpload {
14 pub fn from_blob(blob: web_sys::Blob) -> Self {
15 Self::Blob {
16 blob,
17 file_name: None,
18 }
19 }
20
21 pub fn from_blob_with_name(blob: web_sys::Blob, file_name: impl Into<String>) -> Self {
22 Self::Blob {
23 blob,
24 file_name: Some(file_name.into()),
25 }
26 }
27
28 pub(crate) fn append_to_form(
29 &self,
30 form: &web_sys::FormData,
31 field_name: &str,
32 ) -> Result<(), crate::ForgeClientError> {
33 match self {
34 Self::File(file) => form
35 .append_with_blob_and_filename(field_name, file, &file.name())
36 .map_err(|_| crate::ForgeClientError::new("UPLOAD_FAILED", "Failed to append file", None)),
37 Self::Blob { blob, file_name } => match file_name {
38 Some(file_name) => form
39 .append_with_blob_and_filename(field_name, blob, file_name)
40 .map_err(|_| crate::ForgeClientError::new("UPLOAD_FAILED", "Failed to append blob", None)),
41 None => form
42 .append_with_blob(field_name, blob)
43 .map_err(|_| crate::ForgeClientError::new("UPLOAD_FAILED", "Failed to append blob", None)),
44 },
45 }
46 }
47}
48
49#[cfg(target_arch = "wasm32")]
50impl From<web_sys::File> for ForgeUpload {
51 fn from(value: web_sys::File) -> Self {
52 Self::File(value)
53 }
54}
55
56#[cfg(target_arch = "wasm32")]
57impl From<web_sys::Blob> for ForgeUpload {
58 fn from(value: web_sys::Blob) -> Self {
59 Self::from_blob(value)
60 }
61}
62
63#[cfg(not(target_arch = "wasm32"))]
64#[derive(Debug, Clone)]
65pub struct ForgeUpload {
66 bytes: Vec<u8>,
67 file_name: Option<String>,
68 content_type: Option<String>,
69}
70
71#[cfg(not(target_arch = "wasm32"))]
72impl ForgeUpload {
73 pub fn from_bytes(bytes: impl Into<Vec<u8>>) -> Self {
74 Self {
75 bytes: bytes.into(),
76 file_name: None,
77 content_type: None,
78 }
79 }
80
81 pub fn from_bytes_with_name(
82 bytes: impl Into<Vec<u8>>,
83 file_name: impl Into<String>,
84 ) -> Self {
85 Self {
86 bytes: bytes.into(),
87 file_name: Some(file_name.into()),
88 content_type: None,
89 }
90 }
91
92 pub fn with_content_type(mut self, content_type: impl Into<String>) -> Self {
93 self.content_type = Some(content_type.into());
94 self
95 }
96
97 pub fn into_part(self) -> Result<reqwest::multipart::Part, crate::ForgeClientError> {
98 let mut part = reqwest::multipart::Part::bytes(self.bytes);
99 if let Some(file_name) = self.file_name {
100 part = part.file_name(file_name);
101 }
102 if let Some(content_type) = self.content_type {
103 part = part
104 .mime_str(&content_type)
105 .map_err(|err| crate::ForgeClientError::new("UPLOAD_FAILED", err.to_string(), None))?;
106 }
107 Ok(part)
108 }
109}