aws_smithy_types/
str_bytes.rs
1use bytes::Bytes;
9use std::str::Utf8Error;
10
11#[non_exhaustive]
36#[derive(Clone, Debug, PartialEq, Eq)]
37pub struct StrBytes {
38 bytes: Bytes,
39}
40
41impl StrBytes {
42 fn new(bytes: Bytes) -> Self {
43 StrBytes { bytes }
44 }
45
46 pub fn as_bytes(&self) -> &Bytes {
48 &self.bytes
49 }
50
51 pub fn as_str(&self) -> &str {
53 unsafe { std::str::from_utf8_unchecked(&self.bytes[..]) }
55 }
56
57 pub fn try_copy_from_slice(slice: &[u8]) -> Result<Self, Utf8Error> {
60 match std::str::from_utf8(slice) {
61 Ok(_) => Ok(StrBytes::new(Bytes::copy_from_slice(slice))),
62 Err(err) => Err(err),
63 }
64 }
65
66 pub fn copy_from_str(string: &str) -> Self {
68 StrBytes::new(Bytes::copy_from_slice(string.as_bytes()))
69 }
70}
71
72impl From<String> for StrBytes {
73 fn from(value: String) -> Self {
74 StrBytes::new(Bytes::from(value))
75 }
76}
77
78impl From<&'static str> for StrBytes {
79 fn from(value: &'static str) -> Self {
80 StrBytes::new(Bytes::from(value))
81 }
82}
83
84impl TryFrom<&'static [u8]> for StrBytes {
85 type Error = Utf8Error;
86
87 fn try_from(value: &'static [u8]) -> Result<Self, Self::Error> {
88 match std::str::from_utf8(value) {
89 Ok(_) => Ok(StrBytes::new(Bytes::from(value))),
90 Err(err) => Err(err),
91 }
92 }
93}
94
95impl TryFrom<Vec<u8>> for StrBytes {
96 type Error = Utf8Error;
97
98 fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
99 match std::str::from_utf8(&value[..]) {
100 Ok(_) => Ok(StrBytes::new(Bytes::from(value))),
101 Err(err) => Err(err),
102 }
103 }
104}
105
106impl TryFrom<Bytes> for StrBytes {
107 type Error = Utf8Error;
108
109 fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
110 match std::str::from_utf8(&bytes[..]) {
111 Ok(_) => Ok(StrBytes::new(bytes)),
112 Err(err) => Err(err),
113 }
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use crate::str_bytes::StrBytes;
120 use bytes::Bytes;
121 use std::str::Utf8Error;
122
123 #[test]
124 fn invalid_utf8_correctly_errors() {
125 let invalid_utf8 = &[0xC3, 0x28][..];
126 assert!(std::str::from_utf8(invalid_utf8).is_err());
127
128 let result: Result<StrBytes, Utf8Error> = invalid_utf8.try_into();
129 assert!(result.is_err());
130
131 let result: Result<StrBytes, Utf8Error> = invalid_utf8.to_vec().try_into();
132 assert!(result.is_err());
133
134 let result: Result<StrBytes, Utf8Error> = Bytes::from_static(invalid_utf8).try_into();
135 assert!(result.is_err());
136 }
137
138 #[test]
139 fn valid_utf8() {
140 let valid_utf8 = "hello";
141 let str_bytes: StrBytes = valid_utf8.into();
142 assert_eq!(valid_utf8.as_bytes(), str_bytes.as_bytes());
143 assert_eq!(valid_utf8, str_bytes.as_str());
144 assert_eq!(valid_utf8, str_bytes.as_str());
145 }
146
147 #[test]
148 fn equals() {
149 let str_bytes: StrBytes = "test".into();
150 assert_eq!(str_bytes, str_bytes);
151 let other_bytes: StrBytes = "foo".into();
152 assert_ne!(str_bytes, other_bytes);
153 }
154}