aws_multipart_upload/write/
mod.rs

1//! A collection of `MultipartWrite` implementations for multipart uploads.
2//!
3//! The module contains implementations [`Upload`] and [`EncodedUpload`],
4//! components for building multipart writers like them, and extension traits
5//! for `MultipartWrite` and `Stream` providing useful combinator methods
6//! supporting multipart uploads.
7use crate::client::UploadClient;
8use crate::client::part::{CompletedParts, PartBody};
9use crate::client::request::{CompletedUpload, SendUploadPart};
10use crate::codec::PartEncoder;
11use crate::error::Error as UploadError;
12use crate::uri::ObjectUriIter;
13
14use bytesize::ByteSize;
15use futures::Stream;
16use multipart_write::stream::{Assemble, Assembled};
17use multipart_write::{FusedMultipartWrite, MultipartStreamExt as _, MultipartWrite};
18
19mod encoded;
20pub use self::encoded::{EncodedUpload, Status};
21
22mod part_buffer;
23pub use self::part_buffer::PartBuffer;
24
25mod upload;
26pub use self::upload::{Upload, UploadSent};
27
28/// A type for creating, building, and completing a multipart upload.
29pub type MultipartUpload<E> = EncodedUpload<E, Upload<PartBuffer>>;
30
31/// Trait alias for a general form of `MultipartUpload`.
32pub trait AwsMultipartUpload<Item>
33where
34    Self: FusedMultipartWrite<Item, Ret = Status, Error = UploadError, Output = CompletedUpload>,
35{
36}
37
38impl<Item, E: PartEncoder<Item>> AwsMultipartUpload<Item> for MultipartUpload<E> {}
39
40/// Extension trait for `MultipartWrite` adding specializations for S3 uploads.
41pub trait UploadWriteExt<Part>: MultipartWrite<Part> {
42    /// Returns a new `MultipartWrite` that uploads to a multipart upload, using
43    /// this writer as a buffer for request futures.
44    fn upload(self, client: &UploadClient, iter: ObjectUriIter) -> Upload<Self>
45    where
46        Self: MultipartWrite<SendUploadPart, Error = UploadError, Output = CompletedParts> + Sized,
47    {
48        Upload::new(self, client, iter)
49    }
50
51    /// Transform this `MultipartWrite` by composing a [`PartEncoder`] in front
52    /// of it, resulting in a new one over any type of value that the encoder
53    /// is capable of writing.
54    ///
55    /// [`PartEncoder`]: crate::codec::PartEncoder
56    fn encoded_upload<E>(
57        self,
58        encoder: E,
59        bytes: ByteSize,
60        part_bytes: ByteSize,
61    ) -> EncodedUpload<E, Self>
62    where
63        Self: MultipartWrite<
64                PartBody,
65                Ret = UploadSent,
66                Error = UploadError,
67                Output = CompletedUpload,
68            > + Sized,
69    {
70        EncodedUpload::new(self, encoder, bytes.as_u64(), part_bytes.as_u64())
71    }
72}
73
74impl<Part, Wr: MultipartWrite<Part>> UploadWriteExt<Part> for Wr {}
75
76/// Future for the result of collecting a stream into a multipart upload.
77pub type CollectUpload<St, U> = Assemble<St, U>;
78
79/// Stream of results from sending an input stream to a multipart upload.
80pub type IntoUpload<St, U, F> = Assembled<St, U, F>;
81
82/// Extension of `Stream` by methods for uploading it.
83pub trait UploadStreamExt: Stream {
84    /// Collect this stream into a multipart upload, returning the result of
85    /// completing the upload in a future.
86    fn collect_upload<U>(self, uploader: U) -> CollectUpload<Self, U>
87    where
88        Self: Sized,
89        U: FusedMultipartWrite<Self::Item, Error = UploadError, Output = CompletedUpload>,
90    {
91        self.assemble(uploader)
92    }
93
94    /// Transform the input stream by writing its items to the uploader `U`,
95    /// producing the next item in the stream by completing the upload when the
96    /// status indicates the upload is complete.
97    ///
98    /// The resulting stream ends when either the input stream is exhausted or
99    /// the uploader is unable to start the next upload after producing an item.
100    fn into_upload<U>(self, uploader: U) -> IntoUpload<Self, U, fn(&Status) -> bool>
101    where
102        Self: Sized,
103        U: FusedMultipartWrite<
104                Self::Item,
105                Ret = Status,
106                Error = UploadError,
107                Output = CompletedUpload,
108            >,
109    {
110        self.assembled(uploader, |status| status.should_complete)
111    }
112
113    /// Transform the input stream by writing its items to the uploader `U`,
114    /// producing the next item in the stream by completing the upload when the
115    /// given closure returns true.
116    fn into_upload_when<U, F>(self, uploader: U, f: F) -> IntoUpload<Self, U, F>
117    where
118        Self: Sized,
119        U: FusedMultipartWrite<Self::Item, Error = UploadError, Output = CompletedUpload>,
120        F: FnMut(&U::Ret) -> bool,
121    {
122        self.assembled(uploader, f)
123    }
124}
125
126impl<St: Stream> UploadStreamExt for St {}