aws_multipart_upload/client/
mod.rs1use self::part::CompletedPart;
2use self::request::*;
3use crate::create_upload::CreateMultipartUploadOutput as CreateResponse;
4use crate::error::{ErrorRepr, Result};
5use crate::uri::ObjectUri;
6
7use futures::future::LocalBoxFuture;
8use std::borrow::Cow;
9use std::fmt::{self, Formatter};
10use std::ops::Deref;
11use std::sync::Arc;
12
13pub mod part;
14pub mod request;
15mod sdk;
16pub use sdk::SdkClient;
17
18pub trait SendRequest {
20 fn send_create_upload_request(
23 &self,
24 req: CreateRequest,
25 ) -> impl Future<Output = Result<UploadData>>;
26
27 fn send_new_part_upload_request(
31 &self,
32 req: UploadPartRequest,
33 ) -> impl Future<Output = Result<CompletedPart>>;
34
35 fn send_complete_upload_request(
39 &self,
40 req: CompleteRequest,
41 ) -> impl Future<Output = Result<CompletedUpload>>;
42
43 fn send_abort_upload_request(&self, req: AbortRequest) -> impl Future<Output = Result<()>>;
46}
47
48impl<D, T> SendRequest for T
49where
50 D: SendRequest,
51 T: Deref<Target = D>,
52{
53 async fn send_create_upload_request(&self, req: CreateRequest) -> Result<UploadData> {
54 self.deref().send_create_upload_request(req).await
55 }
56
57 async fn send_new_part_upload_request(&self, req: UploadPartRequest) -> Result<CompletedPart> {
58 self.deref().send_new_part_upload_request(req).await
59 }
60
61 async fn send_complete_upload_request(&self, req: CompleteRequest) -> Result<CompletedUpload> {
62 self.deref().send_complete_upload_request(req).await
63 }
64
65 async fn send_abort_upload_request(&self, req: AbortRequest) -> Result<()> {
66 self.deref().send_abort_upload_request(req).await
67 }
68}
69
70#[derive(Clone)]
75pub struct UploadClient {
76 pub(crate) inner: Arc<dyn BoxedSendRequest>,
77}
78
79impl UploadClient {
80 pub fn new<C>(client: C) -> Self
82 where
83 C: SendRequest + 'static,
84 {
85 let inner = SendRequestInner::new(client);
86 Self {
87 inner: Arc::new(inner),
88 }
89 }
90}
91
92impl SendRequest for UploadClient {
93 async fn send_create_upload_request(&self, req: CreateRequest) -> Result<UploadData> {
94 self.inner.send_create_upload(req).await
95 }
96
97 async fn send_new_part_upload_request(&self, req: UploadPartRequest) -> Result<CompletedPart> {
98 self.inner.send_upload_part(req).await
99 }
100
101 async fn send_complete_upload_request(&self, req: CompleteRequest) -> Result<CompletedUpload> {
102 self.inner.send_complete_upload(req).await
103 }
104
105 async fn send_abort_upload_request(&self, req: AbortRequest) -> Result<()> {
106 self.inner.send_abort_upload(req).await
107 }
108}
109
110impl fmt::Debug for UploadClient {
111 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
112 f.debug_struct("UploadClient")
113 .field("inner", &"SendRequest")
114 .finish()
115 }
116}
117
118#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
120pub struct UploadId(Cow<'static, str>);
121
122impl UploadId {
123 pub(crate) fn new<T: Into<Cow<'static, str>>>(id: T) -> Self {
124 Self(id.into())
125 }
126
127 pub(crate) fn try_from_create_resp(value: &CreateResponse) -> Result<Self, ErrorRepr> {
128 value
129 .upload_id
130 .as_deref()
131 .map(Self::from)
132 .ok_or_else(|| ErrorRepr::Missing("CreateResponse", "upload_id"))
133 }
134
135 pub(crate) fn is_empty(&self) -> bool {
136 self.0.is_empty()
137 }
138}
139
140impl Deref for UploadId {
141 type Target = str;
142
143 fn deref(&self) -> &str {
144 &self.0
145 }
146}
147
148impl fmt::Display for UploadId {
149 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
150 self.0.fmt(f)
151 }
152}
153
154impl From<&str> for UploadId {
155 fn from(value: &str) -> Self {
156 Self::new(value.to_string())
157 }
158}
159
160impl From<String> for UploadId {
161 fn from(value: String) -> Self {
162 Self(Cow::Owned(value))
163 }
164}
165
166#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
176pub struct UploadData {
177 pub id: UploadId,
179 pub uri: ObjectUri,
181}
182
183impl UploadData {
184 pub fn new<T, U>(id: T, uri: U) -> Self
186 where
187 T: Into<UploadId>,
188 U: Into<ObjectUri>,
189 {
190 Self {
191 id: id.into(),
192 uri: uri.into(),
193 }
194 }
195
196 pub fn get_id(&self) -> UploadId {
198 self.id.clone()
199 }
200
201 pub fn get_uri(&self) -> ObjectUri {
203 self.uri.clone()
204 }
205}
206
207pub(crate) trait BoxedSendRequest {
209 fn send_create_upload(&self, req: CreateRequest) -> LocalBoxFuture<'_, Result<UploadData>>;
210
211 fn send_upload_part(&self, req: UploadPartRequest)
212 -> LocalBoxFuture<'_, Result<CompletedPart>>;
213
214 fn send_complete_upload(
215 &self,
216 req: CompleteRequest,
217 ) -> LocalBoxFuture<'_, Result<CompletedUpload>>;
218
219 fn send_abort_upload(&self, req: AbortRequest) -> LocalBoxFuture<'_, Result<()>>;
220}
221
222struct SendRequestInner<T>(T);
225
226impl<T: SendRequest> SendRequestInner<T> {
227 pub(super) fn new(inner: T) -> Self {
228 Self(inner)
229 }
230}
231
232impl<T: SendRequest> BoxedSendRequest for SendRequestInner<T> {
233 fn send_create_upload(&self, req: CreateRequest) -> LocalBoxFuture<'_, Result<UploadData>> {
234 Box::pin(self.0.send_create_upload_request(req))
235 }
236
237 fn send_upload_part(
238 &self,
239 req: UploadPartRequest,
240 ) -> LocalBoxFuture<'_, Result<CompletedPart>> {
241 Box::pin(self.0.send_new_part_upload_request(req))
242 }
243
244 fn send_complete_upload(
245 &self,
246 req: CompleteRequest,
247 ) -> LocalBoxFuture<'_, Result<CompletedUpload>> {
248 Box::pin(self.0.send_complete_upload_request(req))
249 }
250
251 fn send_abort_upload(&self, req: AbortRequest) -> LocalBoxFuture<'_, Result<()>> {
252 Box::pin(self.0.send_abort_upload_request(req))
253 }
254}