s3_wire/operation/multipart/
managed.rs1use std::collections::BTreeMap;
2use std::fmt;
3use std::path::{Path, PathBuf};
4
5use bytes::Bytes;
6
7use super::{CompletedPart, MultipartError, UploadId};
8use crate::operation::{ChecksumAlgorithm, ObjectKey, RequestIds};
9
10#[derive(Clone, Debug, Eq, PartialEq)]
12pub struct CreateMultipartUploadRequest {
13 pub key: ObjectKey,
15 pub content_type: Option<String>,
17 pub user_metadata: BTreeMap<String, String>,
19 pub checksum_algorithm: Option<ChecksumAlgorithm>,
21}
22
23impl CreateMultipartUploadRequest {
24 pub fn new(key: ObjectKey) -> Self {
26 Self {
27 key,
28 content_type: None,
29 user_metadata: BTreeMap::new(),
30 checksum_algorithm: None,
31 }
32 }
33}
34
35#[derive(Clone, Debug, Eq, PartialEq)]
37pub struct CreateMultipartUploadOutput {
38 pub bucket: Option<String>,
40 pub key: ObjectKey,
42 upload_id: UploadId,
44 pub checksum_algorithm: Option<String>,
46 pub request_ids: RequestIds,
48}
49
50impl CreateMultipartUploadOutput {
51 pub(crate) fn new(
52 bucket: Option<String>,
53 key: ObjectKey,
54 upload_id: UploadId,
55 checksum_algorithm: Option<String>,
56 ) -> Self {
57 Self {
58 bucket,
59 key,
60 upload_id,
61 checksum_algorithm,
62 request_ids: RequestIds::default(),
63 }
64 }
65
66 pub const fn upload_id(&self) -> &UploadId {
68 &self.upload_id
69 }
70}
71
72#[derive(Clone, Debug, Eq, PartialEq)]
74pub struct MultipartUpload {
75 key: ObjectKey,
76 upload_id: UploadId,
77 completed_parts: Vec<CompletedPart>,
79}
80
81pub(crate) enum MultipartUploadSource {
82 Bytes(Bytes),
83 File(PathBuf),
84}
85
86pub struct ManagedMultipartUploadRequest {
92 pub(crate) key: ObjectKey,
93 pub(crate) source: MultipartUploadSource,
94 pub(crate) content_type: Option<String>,
95 pub(crate) user_metadata: BTreeMap<String, String>,
96}
97
98impl ManagedMultipartUploadRequest {
99 pub fn from_bytes(key: ObjectKey, bytes: impl Into<Bytes>) -> Self {
101 Self {
102 key,
103 source: MultipartUploadSource::Bytes(bytes.into()),
104 content_type: None,
105 user_metadata: BTreeMap::new(),
106 }
107 }
108
109 pub fn from_path(key: ObjectKey, path: impl AsRef<Path>) -> Self {
114 Self {
115 key,
116 source: MultipartUploadSource::File(path.as_ref().to_owned()),
117 content_type: None,
118 user_metadata: BTreeMap::new(),
119 }
120 }
121
122 pub fn with_content_type(mut self, content_type: impl Into<String>) -> Self {
124 self.content_type = Some(content_type.into());
125 self
126 }
127
128 pub fn with_metadata(mut self, name: impl Into<String>, value: impl Into<String>) -> Self {
130 self.user_metadata.insert(name.into(), value.into());
131 self
132 }
133
134 pub const fn key(&self) -> &ObjectKey {
136 &self.key
137 }
138}
139
140impl fmt::Debug for ManagedMultipartUploadRequest {
141 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
142 formatter
143 .debug_struct("ManagedMultipartUploadRequest")
144 .field("key", &self.key)
145 .field(
146 "source",
147 &match self.source {
148 MultipartUploadSource::Bytes(_) => "bytes",
149 MultipartUploadSource::File(_) => "file",
150 },
151 )
152 .field("content_type", &self.content_type)
153 .field(
154 "user_metadata_names",
155 &self.user_metadata.keys().collect::<Vec<_>>(),
156 )
157 .finish()
158 }
159}
160
161impl MultipartUpload {
162 pub fn new(key: ObjectKey, upload_id: UploadId) -> Self {
164 Self {
165 key,
166 upload_id,
167 completed_parts: Vec::new(),
168 }
169 }
170
171 pub fn record_part(&mut self, part: CompletedPart) -> Result<(), MultipartError> {
173 match self
174 .completed_parts
175 .binary_search_by_key(&part.part_number(), CompletedPart::part_number)
176 {
177 Ok(_) => Err(MultipartError::DuplicatePart(part.part_number())),
178 Err(index) => {
179 self.completed_parts.insert(index, part);
180 Ok(())
181 }
182 }
183 }
184
185 pub fn completed_parts(&self) -> &[CompletedPart] {
187 &self.completed_parts
188 }
189
190 pub const fn key(&self) -> &ObjectKey {
192 &self.key
193 }
194
195 pub const fn upload_id(&self) -> &UploadId {
197 &self.upload_id
198 }
199}