aws_multipart_upload/client/
mod.rs1use std::borrow::Cow;
2use std::fmt::{self, Formatter};
3use std::ops::Deref;
4use std::sync::Arc;
5
6use futures::future::{BoxFuture, Future};
7
8use self::part::CompletedPart;
9use self::request::*;
10use crate::create_upload::CreateMultipartUploadOutput as CreateResponse;
11use crate::error::{ErrorRepr, Result};
12use crate::uri::ObjectUri;
13
14pub mod part;
15pub mod request;
16
17mod sdk;
18pub use sdk::SdkClient;
19
20pub trait UploadApi: Send + Sync {
22 fn send_create_upload_request(
25 &self,
26 req: CreateRequest,
27 ) -> impl Future<Output = Result<UploadData>> + Send;
28
29 fn send_new_part_upload_request(
33 &self,
34 req: UploadPartRequest,
35 ) -> impl Future<Output = Result<CompletedPart>> + Send;
36
37 fn send_complete_upload_request(
41 &self,
42 req: CompleteRequest,
43 ) -> impl Future<Output = Result<CompletedUpload>> + Send;
44
45 fn send_abort_upload_request(
48 &self,
49 req: AbortRequest,
50 ) -> impl Future<Output = Result<()>> + Send;
51}
52
53impl<D, T> UploadApi for T
54where
55 D: UploadApi,
56 T: Deref<Target = D> + Send + Sync,
57{
58 async fn send_create_upload_request(
59 &self,
60 req: CreateRequest,
61 ) -> Result<UploadData> {
62 self.deref().send_create_upload_request(req).await
63 }
64
65 async fn send_new_part_upload_request(
66 &self,
67 req: UploadPartRequest,
68 ) -> Result<CompletedPart> {
69 self.deref().send_new_part_upload_request(req).await
70 }
71
72 async fn send_complete_upload_request(
73 &self,
74 req: CompleteRequest,
75 ) -> Result<CompletedUpload> {
76 self.deref().send_complete_upload_request(req).await
77 }
78
79 async fn send_abort_upload_request(&self, req: AbortRequest) -> Result<()> {
80 self.deref().send_abort_upload_request(req).await
81 }
82}
83
84#[derive(Clone)]
89pub struct UploadClient {
90 pub(crate) inner: Arc<dyn BoxedUploadApi>,
91}
92
93impl UploadClient {
94 pub fn new<C>(client: C) -> Self
96 where
97 C: UploadApi + 'static,
98 {
99 let inner = UploadApiInner::new(client);
100 Self { inner: Arc::new(inner) }
101 }
102}
103
104impl UploadApi for UploadClient {
105 async fn send_create_upload_request(
106 &self,
107 req: CreateRequest,
108 ) -> Result<UploadData> {
109 self.inner.send_create_upload(req).await
110 }
111
112 async fn send_new_part_upload_request(
113 &self,
114 req: UploadPartRequest,
115 ) -> Result<CompletedPart> {
116 self.inner.send_upload_part(req).await
117 }
118
119 async fn send_complete_upload_request(
120 &self,
121 req: CompleteRequest,
122 ) -> Result<CompletedUpload> {
123 self.inner.send_complete_upload(req).await
124 }
125
126 async fn send_abort_upload_request(&self, req: AbortRequest) -> Result<()> {
127 self.inner.send_abort_upload(req).await
128 }
129}
130
131impl fmt::Debug for UploadClient {
132 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
133 f.debug_struct("UploadClient").field("inner", &"UploadApi").finish()
134 }
135}
136
137#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
139pub struct UploadId(Cow<'static, str>);
140
141impl UploadId {
142 pub(crate) fn new<T: Into<Cow<'static, str>>>(id: T) -> Self {
143 Self(id.into())
144 }
145
146 pub(crate) fn try_from_create_resp(
147 value: &CreateResponse,
148 ) -> Result<Self, ErrorRepr> {
149 value
150 .upload_id
151 .as_deref()
152 .map(Self::from)
153 .ok_or_else(|| ErrorRepr::Missing("CreateResponse", "upload_id"))
154 }
155
156 pub(crate) fn is_empty(&self) -> bool {
157 self.0.is_empty()
158 }
159}
160
161impl Deref for UploadId {
162 type Target = str;
163
164 fn deref(&self) -> &str {
165 &self.0
166 }
167}
168
169impl fmt::Display for UploadId {
170 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
171 self.0.fmt(f)
172 }
173}
174
175impl From<&str> for UploadId {
176 fn from(value: &str) -> Self {
177 Self::new(value.to_string())
178 }
179}
180
181impl From<String> for UploadId {
182 fn from(value: String) -> Self {
183 Self(Cow::Owned(value))
184 }
185}
186
187#[derive(Debug, Clone)]
189pub struct UploadData {
190 pub(crate) id: UploadId,
191 pub(crate) uri: ObjectUri,
192}
193
194impl UploadData {
195 pub fn new<T, U>(id: T, uri: U) -> Self
197 where
198 T: Into<UploadId>,
199 U: Into<ObjectUri>,
200 {
201 Self { id: id.into(), uri: uri.into() }
202 }
203
204 pub fn id_ref(&self) -> &UploadId {
206 &self.id
207 }
208
209 pub fn get_id(&self) -> UploadId {
211 self.id.clone()
212 }
213
214 pub fn uri_ref(&self) -> &ObjectUri {
216 &self.uri
217 }
218
219 pub fn get_uri(&self) -> ObjectUri {
221 self.uri.clone()
222 }
223}
224
225pub(crate) trait BoxedUploadApi: Send + Sync {
227 fn send_create_upload(
228 &self,
229 req: CreateRequest,
230 ) -> BoxFuture<'_, Result<UploadData>>;
231
232 fn send_upload_part(
233 &self,
234 req: UploadPartRequest,
235 ) -> BoxFuture<'_, Result<CompletedPart>>;
236
237 fn send_complete_upload(
238 &self,
239 req: CompleteRequest,
240 ) -> BoxFuture<'_, Result<CompletedUpload>>;
241
242 fn send_abort_upload(&self, req: AbortRequest)
243 -> BoxFuture<'_, Result<()>>;
244}
245
246struct UploadApiInner<T>(T);
249
250impl<T: UploadApi> UploadApiInner<T> {
251 pub(super) fn new(inner: T) -> Self {
252 Self(inner)
253 }
254}
255
256impl<T: UploadApi> BoxedUploadApi for UploadApiInner<T> {
257 fn send_create_upload(
258 &self,
259 req: CreateRequest,
260 ) -> BoxFuture<'_, Result<UploadData>> {
261 Box::pin(self.0.send_create_upload_request(req))
262 }
263
264 fn send_upload_part(
265 &self,
266 req: UploadPartRequest,
267 ) -> BoxFuture<'_, Result<CompletedPart>> {
268 Box::pin(self.0.send_new_part_upload_request(req))
269 }
270
271 fn send_complete_upload(
272 &self,
273 req: CompleteRequest,
274 ) -> BoxFuture<'_, Result<CompletedUpload>> {
275 Box::pin(self.0.send_complete_upload_request(req))
276 }
277
278 fn send_abort_upload(
279 &self,
280 req: AbortRequest,
281 ) -> BoxFuture<'_, Result<()>> {
282 Box::pin(self.0.send_abort_upload_request(req))
283 }
284}