scuffle_bytes_util/cow/bytes/
mod.rs1use std::borrow::Cow;
2use std::hash::Hash;
3
4use bytes::Bytes;
5
6#[cfg(feature = "serde")]
7pub(crate) mod serde;
8
9#[derive(Debug, Clone, Eq)]
11pub enum BytesCow<'a> {
12 Slice(&'a [u8]),
14 StaticSlice(&'static [u8]),
16 Vec(Vec<u8>),
18 Bytes(Bytes),
20}
21
22impl Default for BytesCow<'_> {
23 fn default() -> Self {
24 Self::new()
25 }
26}
27
28impl<'a> BytesCow<'a> {
29 pub fn new() -> Self {
31 Self::from_static(b"")
32 }
33
34 pub fn from_static(slice: &'static [u8]) -> Self {
36 Self::StaticSlice(slice)
37 }
38
39 pub fn from_slice(slice: &'a [u8]) -> Self {
41 Self::Slice(slice)
42 }
43
44 pub fn from_bytes(bytes: Bytes) -> Self {
46 Self::Bytes(bytes)
47 }
48
49 pub fn from_cow(cow: Cow<'a, [u8]>) -> Self {
51 match cow {
52 Cow::Borrowed(slice) => Self::Slice(slice),
53 Cow::Owned(bytes) => Self::Vec(bytes),
54 }
55 }
56
57 pub fn from_vec(bytes: Vec<u8>) -> Self {
59 Self::Vec(bytes)
60 }
61
62 pub fn into_bytes(self) -> Bytes {
64 match self {
65 Self::Slice(slice) => Bytes::copy_from_slice(slice),
66 Self::StaticSlice(slice) => Bytes::from_static(slice),
67 Self::Vec(bytes) => Bytes::from(bytes),
68 Self::Bytes(bytes) => bytes,
69 }
70 }
71
72 pub fn as_bytes(&self) -> &[u8] {
74 match self {
75 Self::Slice(slice) => slice,
76 Self::StaticSlice(slice) => slice,
77 Self::Vec(bytes) => bytes.as_slice(),
78 Self::Bytes(bytes) => bytes.as_ref(),
79 }
80 }
81}
82
83impl<T> PartialEq<T> for BytesCow<'_>
84where
85 T: AsRef<[u8]>,
86{
87 fn eq(&self, other: &T) -> bool {
88 self.as_bytes() == other.as_ref()
89 }
90}
91
92impl Hash for BytesCow<'_> {
93 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
94 self.as_bytes().hash(state);
95 }
96}
97
98impl AsRef<[u8]> for BytesCow<'_> {
99 fn as_ref(&self) -> &[u8] {
100 self.as_bytes()
101 }
102}
103
104impl<'a> From<Cow<'a, [u8]>> for BytesCow<'a> {
105 fn from(cow: Cow<'a, [u8]>) -> Self {
106 BytesCow::from_cow(cow)
107 }
108}
109
110impl From<Bytes> for BytesCow<'_> {
111 fn from(bytes: Bytes) -> Self {
112 BytesCow::from_bytes(bytes)
113 }
114}
115
116impl<'a> From<&'a [u8]> for BytesCow<'a> {
117 fn from(bytes: &'a [u8]) -> Self {
118 BytesCow::from_slice(bytes)
119 }
120}
121
122impl From<Vec<u8>> for BytesCow<'_> {
123 fn from(bytes: Vec<u8>) -> Self {
124 BytesCow::from_vec(bytes)
125 }
126}
127
128#[cfg(test)]
129#[cfg_attr(all(test, coverage_nightly), coverage(off))]
130mod tests {
131 use super::BytesCow;
132
133 #[test]
134 fn constructors() {
135 let cow = BytesCow::default();
136 assert_eq!(cow.as_bytes(), b"");
137
138 let cow = BytesCow::from_static(b"hello");
139 assert_eq!(cow.as_bytes(), b"hello");
140
141 let cow = BytesCow::from_slice(b"world");
142 assert_eq!(cow.as_bytes(), b"world");
143
144 let cow = BytesCow::from_vec(vec![1, 2, 3]);
145 assert_eq!(cow.as_bytes(), &[1, 2, 3]);
146 let cow = BytesCow::from(vec![1, 2, 3]);
147 assert_eq!(cow.as_bytes(), &[1, 2, 3]);
148
149 let cow = BytesCow::from_bytes(bytes::Bytes::from_static(b"foo"));
150 assert_eq!(cow.as_bytes(), b"foo");
151 let cow = BytesCow::from(bytes::Bytes::from(vec![7, 8, 9]));
152 assert_eq!(cow.as_bytes(), &[7, 8, 9]);
153
154 let cow = BytesCow::from_cow(std::borrow::Cow::Borrowed(b"bar"));
155 assert_eq!(cow.as_bytes(), b"bar");
156 let cow = BytesCow::from_cow(std::borrow::Cow::Owned(vec![10, 11, 12]));
157 assert_eq!(cow.as_bytes(), &[10, 11, 12]);
158 let cow = BytesCow::from(std::borrow::Cow::Owned(vec![4, 5, 6]));
159 assert_eq!(cow.as_bytes(), &[4, 5, 6]);
160
161 let cow = BytesCow::from(&b"hello world"[..]);
162 assert_eq!(cow.as_bytes(), b"hello world");
163 }
164
165 #[test]
166 fn into_bytes() {
167 let cow = BytesCow::from_static(b"hello");
168 assert_eq!(cow.into_bytes(), bytes::Bytes::from_static(b"hello"));
169
170 let cow = BytesCow::from_slice(b"world");
171 assert_eq!(cow.into_bytes(), bytes::Bytes::from_static(b"world"));
172
173 let cow = BytesCow::from_vec(vec![1, 2, 3]);
174 assert_eq!(cow.into_bytes(), bytes::Bytes::from(vec![1, 2, 3]));
175
176 let cow = BytesCow::from_bytes(bytes::Bytes::from_static(b"foo"));
177 assert_eq!(cow.into_bytes(), bytes::Bytes::from_static(b"foo"));
178
179 let cow = BytesCow::from_cow(std::borrow::Cow::Borrowed(b"bar"));
180 assert_eq!(cow.into_bytes(), bytes::Bytes::from_static(b"bar"));
181
182 let cow = BytesCow::from_cow(std::borrow::Cow::Owned(vec![10, 11, 12]));
183 assert_eq!(cow.into_bytes(), bytes::Bytes::from(vec![10, 11, 12]));
184 }
185
186 #[test]
187 fn as_ref() {
188 let cow = BytesCow::from_static(b"hello");
189 assert_eq!(cow.as_ref(), b"hello");
190
191 let cow = BytesCow::from_slice(b"world");
192 assert_eq!(cow.as_ref(), b"world");
193
194 let cow = BytesCow::from_vec(vec![1, 2, 3]);
195 assert_eq!(cow.as_ref(), &[1, 2, 3]);
196
197 let cow = BytesCow::from_bytes(bytes::Bytes::from_static(b"foo"));
198 assert_eq!(cow.as_ref(), b"foo");
199 }
200
201 #[test]
202 fn partial_eq() {
203 let cow = BytesCow::from_static(b"hello");
204 assert!(cow == b"hello");
205 assert!(cow != b"world");
206
207 let cow = BytesCow::from_slice(b"world");
208 assert!(cow == b"world");
209 assert!(cow != b"hello");
210
211 let cow = BytesCow::from_vec(vec![1, 2, 3]);
212 assert!(cow == [1, 2, 3]);
213 assert!(cow != [4, 5, 6]);
214 }
215
216 #[test]
217 fn hash() {
218 use std::collections::hash_map::DefaultHasher;
219 use std::hash::{Hash, Hasher};
220
221 let mut hasher = DefaultHasher::new();
222 b"hello".hash(&mut hasher);
223 let expected_hash = hasher.finish();
224
225 let cow = BytesCow::from_static(b"hello");
226 let mut hasher = DefaultHasher::new();
227 cow.hash(&mut hasher);
228 assert_eq!(hasher.finish(), expected_hash);
229 }
230}