1 | macro_rules! impl_partial_eq { |
2 | ($lhs:ty, $rhs:ty) => { |
3 | impl<'a, 'b> PartialEq<$rhs> for $lhs { |
4 | #[inline] |
5 | fn eq(&self, other: &$rhs) -> bool { |
6 | let l = self.as_ref(); |
7 | let r: &Self = other.as_ref(); |
8 | PartialEq::eq(l, r) |
9 | } |
10 | } |
11 | |
12 | impl<'a, 'b> PartialEq<$lhs> for $rhs { |
13 | #[inline] |
14 | fn eq(&self, other: &$lhs) -> bool { |
15 | PartialEq::eq(other, self) |
16 | } |
17 | } |
18 | }; |
19 | } |
20 | |
21 | macro_rules! impl_partial_ord { |
22 | ($lhs:ty, $rhs:ty) => { |
23 | impl<'a, 'b> PartialOrd<$rhs> for $lhs { |
24 | #[inline] |
25 | fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> { |
26 | let l = self.as_ref(); |
27 | let r: &Self = other.as_ref(); |
28 | PartialOrd::partial_cmp(l, r) |
29 | } |
30 | } |
31 | |
32 | impl<'a, 'b> PartialOrd<$lhs> for $rhs { |
33 | #[inline] |
34 | fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> { |
35 | PartialOrd::partial_cmp(other, self) |
36 | } |
37 | } |
38 | }; |
39 | } |
40 | |
41 | mod bytes { |
42 | use crate::lib::std::{cmp::Ordering, fmt, ops}; |
43 | |
44 | use crate::stream::Bytes; |
45 | |
46 | impl fmt::Display for Bytes { |
47 | #[inline ] |
48 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
49 | <Self as fmt::UpperHex>::fmt(self, f) |
50 | } |
51 | } |
52 | |
53 | impl fmt::Debug for Bytes { |
54 | #[inline ] |
55 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
56 | <Self as fmt::UpperHex>::fmt(self, f) |
57 | } |
58 | } |
59 | |
60 | impl fmt::LowerHex for Bytes { |
61 | #[inline ] |
62 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
63 | for byte in self.as_bytes() { |
64 | write!(f, " {:0>2x}" , byte)?; |
65 | } |
66 | Ok(()) |
67 | } |
68 | } |
69 | |
70 | impl fmt::UpperHex for Bytes { |
71 | #[inline ] |
72 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
73 | for (i, byte) in self.as_bytes().iter().enumerate() { |
74 | if 0 < i { |
75 | let absolute = (self.as_bytes().as_ptr() as usize) + i; |
76 | if f.alternate() && absolute != 0 && absolute % 4 == 0 { |
77 | write!(f, "_" )?; |
78 | } |
79 | } |
80 | write!(f, " {:0>2X}" , byte)?; |
81 | } |
82 | Ok(()) |
83 | } |
84 | } |
85 | |
86 | impl ops::Deref for Bytes { |
87 | type Target = [u8]; |
88 | |
89 | #[inline ] |
90 | fn deref(&self) -> &[u8] { |
91 | self.as_bytes() |
92 | } |
93 | } |
94 | |
95 | impl ops::Index<usize> for Bytes { |
96 | type Output = u8; |
97 | |
98 | #[inline ] |
99 | fn index(&self, idx: usize) -> &u8 { |
100 | &self.as_bytes()[idx] |
101 | } |
102 | } |
103 | |
104 | impl ops::Index<ops::RangeFull> for Bytes { |
105 | type Output = Bytes; |
106 | |
107 | #[inline ] |
108 | fn index(&self, _: ops::RangeFull) -> &Bytes { |
109 | self |
110 | } |
111 | } |
112 | |
113 | impl ops::Index<ops::Range<usize>> for Bytes { |
114 | type Output = Bytes; |
115 | |
116 | #[inline ] |
117 | fn index(&self, r: ops::Range<usize>) -> &Bytes { |
118 | Bytes::new(&self.as_bytes()[r.start..r.end]) |
119 | } |
120 | } |
121 | |
122 | impl ops::Index<ops::RangeInclusive<usize>> for Bytes { |
123 | type Output = Bytes; |
124 | |
125 | #[inline ] |
126 | fn index(&self, r: ops::RangeInclusive<usize>) -> &Bytes { |
127 | Bytes::new(&self.as_bytes()[*r.start()..=*r.end()]) |
128 | } |
129 | } |
130 | |
131 | impl ops::Index<ops::RangeFrom<usize>> for Bytes { |
132 | type Output = Bytes; |
133 | |
134 | #[inline ] |
135 | fn index(&self, r: ops::RangeFrom<usize>) -> &Bytes { |
136 | Bytes::new(&self.as_bytes()[r.start..]) |
137 | } |
138 | } |
139 | |
140 | impl ops::Index<ops::RangeTo<usize>> for Bytes { |
141 | type Output = Bytes; |
142 | |
143 | #[inline ] |
144 | fn index(&self, r: ops::RangeTo<usize>) -> &Bytes { |
145 | Bytes::new(&self.as_bytes()[..r.end]) |
146 | } |
147 | } |
148 | |
149 | impl ops::Index<ops::RangeToInclusive<usize>> for Bytes { |
150 | type Output = Bytes; |
151 | |
152 | #[inline ] |
153 | fn index(&self, r: ops::RangeToInclusive<usize>) -> &Bytes { |
154 | Bytes::new(&self.as_bytes()[..=r.end]) |
155 | } |
156 | } |
157 | |
158 | impl AsRef<[u8]> for Bytes { |
159 | #[inline ] |
160 | fn as_ref(&self) -> &[u8] { |
161 | self.as_bytes() |
162 | } |
163 | } |
164 | |
165 | impl AsRef<Bytes> for [u8] { |
166 | #[inline ] |
167 | fn as_ref(&self) -> &Bytes { |
168 | Bytes::new(self) |
169 | } |
170 | } |
171 | |
172 | impl AsRef<Bytes> for str { |
173 | #[inline ] |
174 | fn as_ref(&self) -> &Bytes { |
175 | Bytes::new(self) |
176 | } |
177 | } |
178 | |
179 | #[cfg (feature = "alloc" )] |
180 | impl crate::lib::std::borrow::ToOwned for Bytes { |
181 | type Owned = crate::lib::std::vec::Vec<u8>; |
182 | |
183 | #[inline ] |
184 | fn to_owned(&self) -> Self::Owned { |
185 | crate::lib::std::vec::Vec::from(self.as_bytes()) |
186 | } |
187 | } |
188 | |
189 | #[cfg (feature = "alloc" )] |
190 | impl crate::lib::std::borrow::Borrow<Bytes> for crate::lib::std::vec::Vec<u8> { |
191 | #[inline ] |
192 | fn borrow(&self) -> &Bytes { |
193 | Bytes::from_bytes(self.as_slice()) |
194 | } |
195 | } |
196 | |
197 | impl<'a> Default for &'a Bytes { |
198 | fn default() -> &'a Bytes { |
199 | Bytes::new(b"" ) |
200 | } |
201 | } |
202 | |
203 | impl<'a> From<&'a [u8]> for &'a Bytes { |
204 | #[inline ] |
205 | fn from(s: &'a [u8]) -> &'a Bytes { |
206 | Bytes::new(s) |
207 | } |
208 | } |
209 | |
210 | impl<'a> From<&'a Bytes> for &'a [u8] { |
211 | #[inline ] |
212 | fn from(s: &'a Bytes) -> &'a [u8] { |
213 | Bytes::as_bytes(s) |
214 | } |
215 | } |
216 | |
217 | impl<'a> From<&'a str> for &'a Bytes { |
218 | #[inline ] |
219 | fn from(s: &'a str) -> &'a Bytes { |
220 | Bytes::new(s.as_bytes()) |
221 | } |
222 | } |
223 | |
224 | impl Eq for Bytes {} |
225 | |
226 | impl PartialEq<Bytes> for Bytes { |
227 | #[inline ] |
228 | fn eq(&self, other: &Bytes) -> bool { |
229 | self.as_bytes() == other.as_bytes() |
230 | } |
231 | } |
232 | |
233 | impl_partial_eq!(Bytes, [u8]); |
234 | impl_partial_eq!(Bytes, &'a [u8]); |
235 | impl_partial_eq!(Bytes, str); |
236 | impl_partial_eq!(Bytes, &'a str); |
237 | |
238 | impl PartialOrd for Bytes { |
239 | #[inline ] |
240 | fn partial_cmp(&self, other: &Bytes) -> Option<Ordering> { |
241 | Some(self.cmp(other)) |
242 | } |
243 | } |
244 | |
245 | impl Ord for Bytes { |
246 | #[inline ] |
247 | fn cmp(&self, other: &Bytes) -> Ordering { |
248 | Ord::cmp(self.as_bytes(), other.as_bytes()) |
249 | } |
250 | } |
251 | |
252 | impl_partial_ord!(Bytes, [u8]); |
253 | impl_partial_ord!(Bytes, &'a [u8]); |
254 | impl_partial_ord!(Bytes, str); |
255 | impl_partial_ord!(Bytes, &'a str); |
256 | |
257 | #[cfg (all(test, feature = "std" ))] |
258 | mod display { |
259 | use crate::stream::Bytes; |
260 | |
261 | #[test ] |
262 | fn clean() { |
263 | assert_eq!(&format!(" {}" , Bytes::new(b"abc" )), "616263" ); |
264 | assert_eq!(&format!(" {}" , Bytes::new(b" \xf0\x28\x8c\xbc" )), "F0288CBC" ); |
265 | } |
266 | } |
267 | |
268 | #[cfg (all(test, feature = "std" ))] |
269 | mod debug { |
270 | use crate::stream::Bytes; |
271 | |
272 | #[test ] |
273 | fn test_debug() { |
274 | assert_eq!( |
275 | "000000206674797069736F6D0000020069736F6D69736F32617663316D70" , |
276 | format!( |
277 | " {:?}" , |
278 | Bytes::new(b" \0\0\0 ftypisom \0\0\x02\0isomiso2avc1mp" ) |
279 | ), |
280 | ); |
281 | } |
282 | |
283 | #[test ] |
284 | fn test_pretty_debug() { |
285 | // Output can change from run-to-run |
286 | format!( |
287 | " {:#?}" , |
288 | Bytes::new(b" \0\0\0 ftypisom \0\0\x02\0isomiso2avc1mp" ) |
289 | ); |
290 | } |
291 | |
292 | #[test ] |
293 | fn test_sliced() { |
294 | // Output can change from run-to-run |
295 | let total = Bytes::new(b"12345678901234567890" ); |
296 | format!(" {:#?}" , total); |
297 | format!(" {:#?}" , &total[1..]); |
298 | format!(" {:#?}" , &total[10..]); |
299 | } |
300 | } |
301 | } |
302 | |
303 | mod bstr { |
304 | use crate::lib::std::{cmp::Ordering, fmt, ops}; |
305 | |
306 | use crate::stream::BStr; |
307 | |
308 | #[cfg (feature = "alloc" )] |
309 | impl fmt::Display for BStr { |
310 | #[inline ] |
311 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
312 | crate::lib::std::string::String::from_utf8_lossy(self.as_bytes()).fmt(f) |
313 | } |
314 | } |
315 | |
316 | impl fmt::Debug for BStr { |
317 | #[inline ] |
318 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
319 | if !f.alternate() { |
320 | write!(f, " \"" )?; |
321 | } |
322 | for byte in self.as_bytes() { |
323 | let c = *byte as char; |
324 | write!(f, " {}" , c.escape_debug())?; |
325 | } |
326 | if !f.alternate() { |
327 | write!(f, " \"" )?; |
328 | } |
329 | Ok(()) |
330 | } |
331 | } |
332 | |
333 | impl ops::Deref for BStr { |
334 | type Target = [u8]; |
335 | |
336 | #[inline ] |
337 | fn deref(&self) -> &[u8] { |
338 | self.as_bytes() |
339 | } |
340 | } |
341 | |
342 | impl ops::Index<usize> for BStr { |
343 | type Output = u8; |
344 | |
345 | #[inline ] |
346 | fn index(&self, idx: usize) -> &u8 { |
347 | &self.as_bytes()[idx] |
348 | } |
349 | } |
350 | |
351 | impl ops::Index<ops::RangeFull> for BStr { |
352 | type Output = BStr; |
353 | |
354 | #[inline ] |
355 | fn index(&self, _: ops::RangeFull) -> &BStr { |
356 | self |
357 | } |
358 | } |
359 | |
360 | impl ops::Index<ops::Range<usize>> for BStr { |
361 | type Output = BStr; |
362 | |
363 | #[inline ] |
364 | fn index(&self, r: ops::Range<usize>) -> &BStr { |
365 | BStr::new(&self.as_bytes()[r.start..r.end]) |
366 | } |
367 | } |
368 | |
369 | impl ops::Index<ops::RangeInclusive<usize>> for BStr { |
370 | type Output = BStr; |
371 | |
372 | #[inline ] |
373 | fn index(&self, r: ops::RangeInclusive<usize>) -> &BStr { |
374 | BStr::new(&self.as_bytes()[*r.start()..=*r.end()]) |
375 | } |
376 | } |
377 | |
378 | impl ops::Index<ops::RangeFrom<usize>> for BStr { |
379 | type Output = BStr; |
380 | |
381 | #[inline ] |
382 | fn index(&self, r: ops::RangeFrom<usize>) -> &BStr { |
383 | BStr::new(&self.as_bytes()[r.start..]) |
384 | } |
385 | } |
386 | |
387 | impl ops::Index<ops::RangeTo<usize>> for BStr { |
388 | type Output = BStr; |
389 | |
390 | #[inline ] |
391 | fn index(&self, r: ops::RangeTo<usize>) -> &BStr { |
392 | BStr::new(&self.as_bytes()[..r.end]) |
393 | } |
394 | } |
395 | |
396 | impl ops::Index<ops::RangeToInclusive<usize>> for BStr { |
397 | type Output = BStr; |
398 | |
399 | #[inline ] |
400 | fn index(&self, r: ops::RangeToInclusive<usize>) -> &BStr { |
401 | BStr::new(&self.as_bytes()[..=r.end]) |
402 | } |
403 | } |
404 | |
405 | impl AsRef<[u8]> for BStr { |
406 | #[inline ] |
407 | fn as_ref(&self) -> &[u8] { |
408 | self.as_bytes() |
409 | } |
410 | } |
411 | |
412 | impl AsRef<BStr> for [u8] { |
413 | #[inline ] |
414 | fn as_ref(&self) -> &BStr { |
415 | BStr::new(self) |
416 | } |
417 | } |
418 | |
419 | impl AsRef<BStr> for str { |
420 | #[inline ] |
421 | fn as_ref(&self) -> &BStr { |
422 | BStr::new(self) |
423 | } |
424 | } |
425 | |
426 | #[cfg (feature = "alloc" )] |
427 | impl crate::lib::std::borrow::ToOwned for BStr { |
428 | type Owned = crate::lib::std::vec::Vec<u8>; |
429 | |
430 | #[inline ] |
431 | fn to_owned(&self) -> Self::Owned { |
432 | crate::lib::std::vec::Vec::from(self.as_bytes()) |
433 | } |
434 | } |
435 | |
436 | #[cfg (feature = "alloc" )] |
437 | impl crate::lib::std::borrow::Borrow<BStr> for crate::lib::std::vec::Vec<u8> { |
438 | #[inline ] |
439 | fn borrow(&self) -> &BStr { |
440 | BStr::from_bytes(self.as_slice()) |
441 | } |
442 | } |
443 | |
444 | impl<'a> Default for &'a BStr { |
445 | fn default() -> &'a BStr { |
446 | BStr::new(b"" ) |
447 | } |
448 | } |
449 | |
450 | impl<'a> From<&'a [u8]> for &'a BStr { |
451 | #[inline ] |
452 | fn from(s: &'a [u8]) -> &'a BStr { |
453 | BStr::new(s) |
454 | } |
455 | } |
456 | |
457 | impl<'a> From<&'a BStr> for &'a [u8] { |
458 | #[inline ] |
459 | fn from(s: &'a BStr) -> &'a [u8] { |
460 | BStr::as_bytes(s) |
461 | } |
462 | } |
463 | |
464 | impl<'a> From<&'a str> for &'a BStr { |
465 | #[inline ] |
466 | fn from(s: &'a str) -> &'a BStr { |
467 | BStr::new(s.as_bytes()) |
468 | } |
469 | } |
470 | |
471 | impl Eq for BStr {} |
472 | |
473 | impl PartialEq<BStr> for BStr { |
474 | #[inline ] |
475 | fn eq(&self, other: &BStr) -> bool { |
476 | self.as_bytes() == other.as_bytes() |
477 | } |
478 | } |
479 | |
480 | impl_partial_eq!(BStr, [u8]); |
481 | impl_partial_eq!(BStr, &'a [u8]); |
482 | impl_partial_eq!(BStr, str); |
483 | impl_partial_eq!(BStr, &'a str); |
484 | |
485 | impl PartialOrd for BStr { |
486 | #[inline ] |
487 | fn partial_cmp(&self, other: &BStr) -> Option<Ordering> { |
488 | Some(self.cmp(other)) |
489 | } |
490 | } |
491 | |
492 | impl Ord for BStr { |
493 | #[inline ] |
494 | fn cmp(&self, other: &BStr) -> Ordering { |
495 | Ord::cmp(self.as_bytes(), other.as_bytes()) |
496 | } |
497 | } |
498 | |
499 | impl_partial_ord!(BStr, [u8]); |
500 | impl_partial_ord!(BStr, &'a [u8]); |
501 | impl_partial_ord!(BStr, str); |
502 | impl_partial_ord!(BStr, &'a str); |
503 | |
504 | #[cfg (all(test, feature = "std" ))] |
505 | mod display { |
506 | use crate::stream::BStr; |
507 | |
508 | #[test ] |
509 | fn clean() { |
510 | assert_eq!(&format!(" {}" , BStr::new(b"abc" )), "abc" ); |
511 | assert_eq!(&format!(" {}" , BStr::new(b" \xf0\x28\x8c\xbc" )), "�(��" ); |
512 | } |
513 | } |
514 | |
515 | #[cfg (all(test, feature = "std" ))] |
516 | mod debug { |
517 | use crate::stream::BStr; |
518 | |
519 | #[test ] |
520 | fn test_debug() { |
521 | assert_eq!(&format!(" {:?}" , BStr::new(b"abc" )), " \"abc \"" ); |
522 | |
523 | assert_eq!( |
524 | " \"\\0 \\0 \\0 ftypisom \\0 \\0 \\u{2} \\0isomiso2avc1mp \"" , |
525 | format!( |
526 | " {:?}" , |
527 | BStr::new(b" \0\0\0 ftypisom \0\0\x02\0isomiso2avc1mp" ) |
528 | ), |
529 | ); |
530 | } |
531 | |
532 | #[test ] |
533 | fn test_pretty_debug() { |
534 | assert_eq!(&format!(" {:#?}" , BStr::new(b"abc" )), "abc" ); |
535 | } |
536 | } |
537 | } |
538 | |