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]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result48          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]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result55          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]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result62          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]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result72          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]
deref(&self) -> &[u8]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]
index(&self, idx: usize) -> &u899          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]
index(&self, _: ops::RangeFull) -> &Bytes108          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]
index(&self, r: ops::Range<usize>) -> &Bytes117          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]
index(&self, r: ops::RangeInclusive<usize>) -> &Bytes126          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]
index(&self, r: ops::RangeFrom<usize>) -> &Bytes135          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]
index(&self, r: ops::RangeTo<usize>) -> &Bytes144          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]
index(&self, r: ops::RangeToInclusive<usize>) -> &Bytes153          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]
as_ref(&self) -> &[u8]160          fn as_ref(&self) -> &[u8] {
161              self.as_bytes()
162          }
163      }
164  
165      impl AsRef<Bytes> for [u8] {
166          #[inline]
as_ref(&self) -> &Bytes167          fn as_ref(&self) -> &Bytes {
168              Bytes::new(self)
169          }
170      }
171  
172      impl AsRef<Bytes> for str {
173          #[inline]
as_ref(&self) -> &Bytes174          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]
to_owned(&self) -> Self::Owned184          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]
borrow(&self) -> &Bytes192          fn borrow(&self) -> &Bytes {
193              Bytes::from_bytes(self.as_slice())
194          }
195      }
196  
197      impl<'a> Default for &'a Bytes {
default() -> &'a Bytes198          fn default() -> &'a Bytes {
199              Bytes::new(b"")
200          }
201      }
202  
203      impl<'a> From<&'a [u8]> for &'a Bytes {
204          #[inline]
from(s: &'a [u8]) -> &'a Bytes205          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]
from(s: &'a Bytes) -> &'a [u8]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]
from(s: &'a str) -> &'a Bytes219          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]
eq(&self, other: &Bytes) -> bool228          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]
partial_cmp(&self, other: &Bytes) -> Option<Ordering>240          fn partial_cmp(&self, other: &Bytes) -> Option<Ordering> {
241              Some(self.cmp(other))
242          }
243      }
244  
245      impl Ord for Bytes {
246          #[inline]
cmp(&self, other: &Bytes) -> Ordering247          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]
clean()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]
test_debug()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]
test_pretty_debug()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]
test_sliced()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]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result311          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]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result318          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]
deref(&self) -> &[u8]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]
index(&self, idx: usize) -> &u8346          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]
index(&self, _: ops::RangeFull) -> &BStr355          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]
index(&self, r: ops::Range<usize>) -> &BStr364          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]
index(&self, r: ops::RangeInclusive<usize>) -> &BStr373          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]
index(&self, r: ops::RangeFrom<usize>) -> &BStr382          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]
index(&self, r: ops::RangeTo<usize>) -> &BStr391          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]
index(&self, r: ops::RangeToInclusive<usize>) -> &BStr400          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]
as_ref(&self) -> &[u8]407          fn as_ref(&self) -> &[u8] {
408              self.as_bytes()
409          }
410      }
411  
412      impl AsRef<BStr> for [u8] {
413          #[inline]
as_ref(&self) -> &BStr414          fn as_ref(&self) -> &BStr {
415              BStr::new(self)
416          }
417      }
418  
419      impl AsRef<BStr> for str {
420          #[inline]
as_ref(&self) -> &BStr421          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]
to_owned(&self) -> Self::Owned431          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]
borrow(&self) -> &BStr439          fn borrow(&self) -> &BStr {
440              BStr::from_bytes(self.as_slice())
441          }
442      }
443  
444      impl<'a> Default for &'a BStr {
default() -> &'a BStr445          fn default() -> &'a BStr {
446              BStr::new(b"")
447          }
448      }
449  
450      impl<'a> From<&'a [u8]> for &'a BStr {
451          #[inline]
from(s: &'a [u8]) -> &'a BStr452          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]
from(s: &'a BStr) -> &'a [u8]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]
from(s: &'a str) -> &'a BStr466          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]
eq(&self, other: &BStr) -> bool475          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]
partial_cmp(&self, other: &BStr) -> Option<Ordering>487          fn partial_cmp(&self, other: &BStr) -> Option<Ordering> {
488              Some(self.cmp(other))
489          }
490      }
491  
492      impl Ord for BStr {
493          #[inline]
cmp(&self, other: &BStr) -> Ordering494          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]
clean()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]
test_debug()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]
test_pretty_debug()533          fn test_pretty_debug() {
534              assert_eq!(&format!("{:#?}", BStr::new(b"abc")), "abc");
535          }
536      }
537  }
538