s3_wire/operation/multipart/
part.rs1use std::{fmt, num::NonZeroU16};
2
3use super::{MultipartError, UploadId};
4use crate::operation::{Checksum, ObjectKey, RequestIds};
5
6#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
8pub struct PartNumber(NonZeroU16);
9
10impl PartNumber {
11 pub const MAX: u16 = 10_000;
13
14 pub fn new(value: u16) -> Option<Self> {
16 NonZeroU16::new(value)
17 .filter(|value| value.get() <= Self::MAX)
18 .map(Self)
19 }
20
21 pub const fn get(self) -> u16 {
23 self.0.get()
24 }
25}
26
27pub struct UploadPartRequest<B> {
29 key: ObjectKey,
30 upload_id: UploadId,
31 part_number: PartNumber,
32 body: B,
33 checksum: Checksum,
34}
35
36impl<B> UploadPartRequest<B> {
37 pub fn new(key: ObjectKey, upload_id: UploadId, part_number: PartNumber, body: B) -> Self {
39 Self {
40 key,
41 upload_id,
42 part_number,
43 body,
44 checksum: Checksum::default(),
45 }
46 }
47
48 pub const fn key(&self) -> &ObjectKey {
50 &self.key
51 }
52
53 pub const fn upload_id(&self) -> &UploadId {
55 &self.upload_id
56 }
57
58 pub const fn part_number(&self) -> PartNumber {
60 self.part_number
61 }
62
63 pub const fn body(&self) -> &B {
65 &self.body
66 }
67
68 pub fn body_mut(&mut self) -> &mut B {
70 &mut self.body
71 }
72
73 pub const fn checksum(&self) -> &Checksum {
75 &self.checksum
76 }
77
78 pub fn with_checksum(mut self, checksum: Checksum) -> Self {
80 self.checksum = checksum;
81 self
82 }
83
84 pub fn into_body(self) -> B {
86 self.body
87 }
88}
89
90impl<B> fmt::Debug for UploadPartRequest<B> {
91 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
92 formatter
93 .debug_struct("UploadPartRequest")
94 .field("key", &self.key)
95 .field("upload_id", &self.upload_id)
96 .field("part_number", &self.part_number)
97 .field("body", &"<stream>")
98 .field("checksum", &self.checksum)
99 .finish()
100 }
101}
102
103#[derive(Clone, Debug, Eq, PartialEq)]
105pub struct UploadPartOutput {
106 pub part_number: PartNumber,
108 pub e_tag: String,
110 pub checksum: Checksum,
112 pub request_ids: RequestIds,
114}
115
116#[derive(Clone, Debug, Eq, PartialEq)]
118pub struct CompletedPart {
119 part_number: PartNumber,
120 e_tag: String,
121 checksum: Checksum,
122}
123
124impl CompletedPart {
125 pub fn new(part_number: u16, e_tag: impl Into<String>) -> Result<Self, MultipartError> {
127 let part_number =
128 PartNumber::new(part_number).ok_or(MultipartError::InvalidPartNumber(part_number))?;
129 let e_tag = e_tag.into();
130 if e_tag.trim().is_empty() {
131 return Err(MultipartError::EmptyETag {
132 part_number: part_number.get(),
133 });
134 }
135 Ok(Self {
136 part_number,
137 e_tag,
138 checksum: Checksum::default(),
139 })
140 }
141
142 pub const fn part_number(&self) -> PartNumber {
144 self.part_number
145 }
146
147 pub fn e_tag(&self) -> &str {
149 &self.e_tag
150 }
151
152 pub const fn checksum(&self) -> &Checksum {
154 &self.checksum
155 }
156
157 pub fn with_checksum(mut self, checksum: Checksum) -> Self {
159 self.checksum = checksum;
160 self
161 }
162}