1use std::{
2 borrow::Borrow,
3 ops::{Deref, DerefMut},
4};
5
6#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
8pub struct Binary(pub Vec<u8>);
9
10impl Binary {
11 pub fn new() -> Self {
13 Binary(Vec::new())
14 }
15
16 pub fn with_capacity(capacity: usize) -> Self {
18 Binary(Vec::with_capacity(capacity))
19 }
20
21 pub fn len(&self) -> usize {
23 self.0.len()
24 }
25
26 pub fn is_empty(&self) -> bool {
28 self.0.is_empty()
29 }
30
31 pub fn capacity(&self) -> usize {
33 self.0.capacity()
34 }
35
36 pub fn reserve(&mut self, additional: usize) {
38 self.0.reserve(additional);
39 }
40
41 pub fn push(&mut self, byte: u8) {
43 self.0.push(byte);
44 }
45
46 pub fn pop(&mut self) -> Option<u8> {
48 self.0.pop()
49 }
50
51 pub fn clear(&mut self) {
53 self.0.clear();
54 }
55
56 pub fn truncate(&mut self, len: usize) {
58 self.0.truncate(len);
59 }
60
61 pub fn extend_from_slice(&mut self, slice: &[u8]) {
63 self.0.extend_from_slice(slice);
64 }
65}
66
67impl From<Vec<u8>> for Binary {
68 fn from(v: Vec<u8>) -> Self {
69 Binary(v)
70 }
71}
72
73impl From<Binary> for Vec<u8> {
74 fn from(binary: Binary) -> Self {
75 binary.0
76 }
77}
78
79impl From<&[u8]> for Binary {
80 fn from(slice: &[u8]) -> Self {
81 Binary(slice.to_vec())
82 }
83}
84
85impl<const N: usize> From<&[u8; N]> for Binary {
86 fn from(arr: &[u8; N]) -> Self {
87 Binary(arr.to_vec())
88 }
89}
90
91impl<const N: usize> From<[u8; N]> for Binary {
92 fn from(arr: [u8; N]) -> Self {
93 Binary(arr.to_vec())
94 }
95}
96
97impl AsRef<[u8]> for Binary {
98 fn as_ref(&self) -> &[u8] {
99 &self.0
100 }
101}
102
103impl AsMut<[u8]> for Binary {
104 fn as_mut(&mut self) -> &mut [u8] {
105 &mut self.0
106 }
107}
108
109impl Deref for Binary {
110 type Target = [u8];
111
112 fn deref(&self) -> &Self::Target {
113 &self.0
114 }
115}
116
117impl DerefMut for Binary {
118 fn deref_mut(&mut self) -> &mut Self::Target {
119 &mut self.0
120 }
121}
122
123impl Borrow<[u8]> for Binary {
124 fn borrow(&self) -> &[u8] {
125 &self.0
126 }
127}
128
129impl PartialEq<[u8]> for Binary {
130 fn eq(&self, other: &[u8]) -> bool {
131 self.0 == other
132 }
133}
134
135impl PartialEq<&[u8]> for Binary {
136 fn eq(&self, other: &&[u8]) -> bool {
137 &self.0 == other
138 }
139}
140
141impl PartialEq<Vec<u8>> for Binary {
142 fn eq(&self, other: &Vec<u8>) -> bool {
143 &self.0 == other
144 }
145}
146
147impl<const N: usize> PartialEq<[u8; N]> for Binary {
148 fn eq(&self, other: &[u8; N]) -> bool {
149 self.0 == other
150 }
151}
152
153impl<const N: usize> PartialEq<&[u8; N]> for Binary {
154 fn eq(&self, other: &&[u8; N]) -> bool {
155 &self.0 == other
156 }
157}
158
159impl FromIterator<u8> for Binary {
160 fn from_iter<I: IntoIterator<Item = u8>>(iter: I) -> Self {
161 Binary(iter.into_iter().collect())
162 }
163}
164
165impl Extend<u8> for Binary {
166 fn extend<I: IntoIterator<Item = u8>>(&mut self, iter: I) {
167 self.0.extend(iter);
168 }
169}
170
171impl IntoIterator for Binary {
172 type Item = u8;
173 type IntoIter = std::vec::IntoIter<u8>;
174
175 fn into_iter(self) -> Self::IntoIter {
176 self.0.into_iter()
177 }
178}
179
180impl<'a> IntoIterator for &'a Binary {
181 type Item = &'a u8;
182 type IntoIter = std::slice::Iter<'a, u8>;
183
184 fn into_iter(self) -> Self::IntoIter {
185 self.0.iter()
186 }
187}
188
189impl<'a> IntoIterator for &'a mut Binary {
190 type Item = &'a mut u8;
191 type IntoIter = std::slice::IterMut<'a, u8>;
192
193 fn into_iter(self) -> Self::IntoIter {
194 self.0.iter_mut()
195 }
196}
197
198#[cfg(test)]
199mod tests {
200 use rstest::rstest;
201
202 use super::*;
203
204 #[rstest]
205 #[case(Binary::from(vec![1u8, 2, 3]), vec![1, 2, 3])]
206 #[case(Binary::from(b"hello"), b"hello".to_vec())]
207 #[case(Binary::from(b"world"), b"world".to_vec())]
208 #[case(Binary::from([1u8, 2, 3]), vec![1, 2, 3])]
209 fn test_binary_from_conversions(#[case] binary: Binary, #[case] expected: Vec<u8>) {
210 assert_eq!(binary, Binary(expected));
211 }
212
213 #[test]
214 fn test_binary_conversions() {
215 let bytes: &[u8] = b"slice";
217 let binary = Binary::from(bytes);
218 assert_eq!(binary, Binary(b"slice".to_vec()));
219
220 let binary = Binary(vec![1, 2, 3]);
222 let vec: Vec<u8> = binary.clone().into();
223 assert_eq!(vec, vec![1, 2, 3]);
224
225 let binary = Binary(vec![4, 5, 6]);
227 let slice: &[u8] = binary.as_ref();
228 assert_eq!(slice, &[4, 5, 6]);
229
230 let binary = Binary(vec![7, 8, 9]);
232 assert_eq!(&*binary, &[7, 8, 9]);
233 assert_eq!(binary.len(), 3);
234 assert_eq!(binary[0], 7);
235
236 let mut binary = Binary(vec![1, 2, 3]);
238 let slice_mut: &mut [u8] = binary.as_mut();
239 slice_mut[0] = 99;
240 assert_eq!(binary.as_ref(), &[99, 2, 3]);
241
242 let mut binary = Binary(vec![4, 5, 6]);
244 binary[1] = 88;
245 assert_eq!(&*binary, &[4, 88, 6]);
246 }
247
248 #[test]
249 fn test_binary_construction() {
250 let binary = Binary::new();
252 assert_eq!(binary.len(), 0);
253 assert!(binary.is_empty());
254
255 let binary = Binary::with_capacity(10);
257 assert_eq!(binary.len(), 0);
258 assert!(binary.capacity() >= 10);
259
260 let binary = Binary::default();
262 assert_eq!(binary, Binary::new());
263 }
264
265 #[rstest]
266 #[case(Binary::new(), 0, true)]
267 #[case(Binary::from(vec![1, 2, 3]), 3, false)]
268 fn test_binary_length_check(
269 #[case] binary: Binary,
270 #[case] len: usize,
271 #[case] is_empty: bool,
272 ) {
273 assert_eq!(binary.len(), len);
274 assert_eq!(binary.is_empty(), is_empty);
275 }
276
277 #[test]
278 fn test_binary_methods() {
279 let mut binary = Binary::new();
280
281 binary.push(1);
283 binary.push(2);
284 binary.push(3);
285 assert_eq!(binary.len(), 3);
286 assert_eq!(&*binary, &[1, 2, 3]);
287
288 assert_eq!(binary.pop(), Some(3));
290 assert_eq!(binary.len(), 2);
291 assert_eq!(&*binary, &[1, 2]);
292
293 binary.extend_from_slice(&[4, 5, 6]);
295 assert_eq!(&*binary, &[1, 2, 4, 5, 6]);
296
297 binary.truncate(3);
299 assert_eq!(binary.len(), 3);
300 assert_eq!(&*binary, &[1, 2, 4]);
301
302 binary.clear();
304 assert_eq!(binary.len(), 0);
305 assert!(binary.is_empty());
306
307 assert_eq!(binary.pop(), None);
309 }
310
311 #[test]
312 fn test_binary_iterators() {
313 let binary = Binary::from(vec![1u8, 2, 3]);
314
315 let vec: Vec<u8> = binary.clone().into_iter().collect();
317 assert_eq!(vec, vec![1, 2, 3]);
318
319 let sum: u8 = (&binary).into_iter().sum();
321 assert_eq!(sum, 6);
322
323 let mut binary = Binary::from(vec![1u8, 2, 3]);
325 for byte in &mut binary {
326 *byte *= 2;
327 }
328 assert_eq!(&*binary, &[2, 4, 6]);
329
330 let binary: Binary = vec![7u8, 8, 9].into_iter().collect();
332 assert_eq!(&*binary, &[7, 8, 9]);
333
334 let mut binary = Binary::from(vec![1u8, 2]);
336 binary.extend(vec![3, 4, 5]);
337 assert_eq!(&*binary, &[1, 2, 3, 4, 5]);
338 }
339
340 #[rstest]
341 #[case(Binary::from(vec![1u8, 2, 3]), &[1u8, 2, 3] as &[u8], true)]
342 #[case(Binary::from(vec![1u8, 2, 3]), &[1u8, 2] as &[u8], false)]
343 #[case(Binary::from(b"hello"), b"hello" as &[u8], true)]
344 #[case(Binary::from(b"hello"), b"world" as &[u8], false)]
345 fn test_binary_slice_eq(#[case] binary: Binary, #[case] slice: &[u8], #[case] should_eq: bool) {
346 if should_eq {
347 assert_eq!(binary, slice);
348 } else {
349 assert_ne!(binary, slice);
350 }
351 }
352
353 #[rstest]
354 #[case(Binary::from(vec![1u8, 2, 3]), vec![1u8, 2, 3], true)]
355 #[case(Binary::from(vec![1u8, 2, 3]), vec![1u8, 2], false)]
356 fn test_binary_vec_eq(#[case] binary: Binary, #[case] vec: Vec<u8>, #[case] should_eq: bool) {
357 if should_eq {
358 assert_eq!(binary, vec);
359 } else {
360 assert_ne!(binary, vec);
361 }
362 }
363
364 #[test]
365 fn test_binary_partial_eq() {
366 let binary = Binary::from(vec![1u8, 2, 3]);
367
368 assert_eq!(binary, [1u8, 2, 3]);
370 assert_ne!(binary, [1u8, 2, 3, 4]);
371
372 let arr: &[u8; 3] = &[1, 2, 3];
374 assert_eq!(binary, arr);
375 }
376
377 #[test]
378 fn test_binary_borrow() {
379 use std::collections::HashMap;
380
381 let mut map: HashMap<Binary, &str> = HashMap::new();
382 let key = Binary::from(vec![1u8, 2, 3]);
383 map.insert(key.clone(), "value");
384
385 let lookup: &[u8] = &[1, 2, 3];
387 assert_eq!(map.get(lookup), Some(&"value"));
388
389 let key2 = Binary::from(b"hello");
391 map.insert(key2.clone(), "world");
392 assert_eq!(map.get(b"hello".as_slice()), Some(&"world"));
393 }
394}