use std::fmt::{self, Debug, Formatter};
use std::pin::Pin;
use std::task::{Context, Poll};
use aws_sdk::types::CompletedMultipartUpload;
use futures::future::BoxFuture;
use super::CompleteRequestBuilder;
use crate::client::part::{CompletedParts, EntityTag};
use crate::client::{UploadClient, UploadData, UploadId};
use crate::error::{ErrorRepr, Result};
use crate::uri::ObjectUri;
pub struct SendCompleteUpload(
pub(crate) BoxFuture<'static, Result<CompletedUpload>>,
);
impl SendCompleteUpload {
pub fn new(client: &UploadClient, req: CompleteRequest) -> Self {
let cli = client.clone();
Self(Box::pin(async move { cli.inner.send_complete_upload(req).await }))
}
}
impl Future for SendCompleteUpload {
type Output = Result<CompletedUpload>;
fn poll(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Self::Output> {
self.0.as_mut().poll(cx)
}
}
impl Debug for SendCompleteUpload {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_tuple("SendCompleteUpload").finish()
}
}
#[derive(Debug, Clone)]
pub struct CompleteRequest {
pub(crate) id: UploadId,
pub(crate) uri: ObjectUri,
pub(crate) completed: CompletedParts,
}
impl CompleteRequest {
pub fn new(data: &UploadData, completed: CompletedParts) -> Self {
Self { id: data.get_id(), uri: data.get_uri(), completed }
}
pub fn with_builder(
&self,
builder: CompleteRequestBuilder,
) -> CompleteRequestBuilder {
let parts = CompletedMultipartUpload::from(&self.completed);
builder
.upload_id(&*self.id)
.bucket(&*self.uri.bucket)
.key(&*self.uri.key)
.multipart_upload(parts)
}
pub fn id(&self) -> &UploadId {
&self.id
}
pub fn uri(&self) -> &ObjectUri {
&self.uri
}
pub fn completed_parts(&self) -> &CompletedParts {
&self.completed
}
pub(crate) fn validate(&self) -> Result<()> {
if self.id.is_empty()
|| self.uri.is_empty()
|| self.completed_parts().count() == 0
{
return Err(ErrorRepr::Missing(
"CompleteUploadRequest",
"invalid upload data",
)
.into());
}
Ok(())
}
}
#[derive(Debug, Clone, Default)]
pub struct CompletedUpload {
pub uri: ObjectUri,
pub etag: EntityTag,
}
impl CompletedUpload {
pub fn new(uri: ObjectUri, etag: EntityTag) -> Self {
Self { uri, etag }
}
}