s3_wire/operation/multipart/
identifier.rs1use std::{fmt, str::FromStr};
2
3#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
9pub struct UploadId(String);
10
11impl UploadId {
12 pub const MAX_LENGTH: usize = 2_048;
18
19 pub fn new(value: impl Into<String>) -> Result<Self, UploadIdError> {
21 let value = value.into();
22 if value.is_empty() {
23 return Err(UploadIdError::Empty);
24 }
25 if value.len() > Self::MAX_LENGTH {
26 return Err(UploadIdError::TooLong {
27 length: value.len(),
28 maximum: Self::MAX_LENGTH,
29 });
30 }
31 if let Some(index) = value.bytes().position(|byte| byte.is_ascii_control()) {
32 return Err(UploadIdError::AsciiControl { index });
33 }
34 Ok(Self(value))
35 }
36
37 pub fn expose(&self) -> &str {
39 &self.0
40 }
41
42 pub fn as_str(&self) -> &str {
44 self.expose()
45 }
46}
47
48impl fmt::Debug for UploadId {
49 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
50 formatter.write_str("UploadId([REDACTED])")
51 }
52}
53
54impl fmt::Display for UploadId {
55 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
56 formatter.write_str("[REDACTED]")
57 }
58}
59
60impl FromStr for UploadId {
61 type Err = UploadIdError;
62
63 fn from_str(value: &str) -> Result<Self, Self::Err> {
64 Self::new(value)
65 }
66}
67
68impl TryFrom<String> for UploadId {
69 type Error = UploadIdError;
70
71 fn try_from(value: String) -> Result<Self, Self::Error> {
72 Self::new(value)
73 }
74}
75
76#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
78pub enum UploadIdError {
79 #[error("multipart upload ID cannot be empty")]
81 Empty,
82 #[error("multipart upload ID is {length} bytes; the maximum is {maximum}")]
84 TooLong {
85 length: usize,
87 maximum: usize,
89 },
90 #[error("multipart upload ID contains an ASCII control at byte {index}")]
92 AsciiControl {
93 index: usize,
95 },
96}