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 other: &[u8] = other.as_ref();
7                 PartialEq::eq(self.as_bytes(), other)
8             }
9         }
10 
11         impl<'a, 'b> PartialEq<$lhs> for $rhs {
12             #[inline]
13             fn eq(&self, other: &$lhs) -> bool {
14                 let this: &[u8] = self.as_ref();
15                 PartialEq::eq(this, other.as_bytes())
16             }
17         }
18     };
19 }
20 
21 #[cfg(feature = "alloc")]
22 macro_rules! impl_partial_eq_cow {
23     ($lhs:ty, $rhs:ty) => {
24         impl<'a, 'b> PartialEq<$rhs> for $lhs {
25             #[inline]
26             fn eq(&self, other: &$rhs) -> bool {
27                 let other: &[u8] = (&**other).as_ref();
28                 PartialEq::eq(self.as_bytes(), other)
29             }
30         }
31 
32         impl<'a, 'b> PartialEq<$lhs> for $rhs {
33             #[inline]
34             fn eq(&self, other: &$lhs) -> bool {
35                 let this: &[u8] = (&**other).as_ref();
36                 PartialEq::eq(this, self.as_bytes())
37             }
38         }
39     };
40 }
41 
42 macro_rules! impl_partial_ord {
43     ($lhs:ty, $rhs:ty) => {
44         impl<'a, 'b> PartialOrd<$rhs> for $lhs {
45             #[inline]
46             fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
47                 let other: &[u8] = other.as_ref();
48                 PartialOrd::partial_cmp(self.as_bytes(), other)
49             }
50         }
51 
52         impl<'a, 'b> PartialOrd<$lhs> for $rhs {
53             #[inline]
54             fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
55                 let this: &[u8] = self.as_ref();
56                 PartialOrd::partial_cmp(this, other.as_bytes())
57             }
58         }
59     };
60 }
61 
62 #[cfg(feature = "alloc")]
63 mod bstring {
64     use core::{
65         cmp::Ordering, convert::TryFrom, fmt, iter::FromIterator, ops,
66     };
67 
68     use alloc::{
69         borrow::{Borrow, Cow, ToOwned},
70         string::String,
71         vec,
72         vec::Vec,
73     };
74 
75     use crate::{
76         bstr::BStr, bstring::BString, ext_slice::ByteSlice, ext_vec::ByteVec,
77     };
78 
79     impl fmt::Display for BString {
80         #[inline]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result81         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82             fmt::Display::fmt(self.as_bstr(), f)
83         }
84     }
85 
86     impl fmt::Debug for BString {
87         #[inline]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result88         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89             fmt::Debug::fmt(self.as_bstr(), f)
90         }
91     }
92 
93     impl ops::Deref for BString {
94         type Target = Vec<u8>;
95 
96         #[inline]
deref(&self) -> &Vec<u8>97         fn deref(&self) -> &Vec<u8> {
98             self.as_vec()
99         }
100     }
101 
102     impl ops::DerefMut for BString {
103         #[inline]
deref_mut(&mut self) -> &mut Vec<u8>104         fn deref_mut(&mut self) -> &mut Vec<u8> {
105             self.as_vec_mut()
106         }
107     }
108 
109     impl AsRef<[u8]> for BString {
110         #[inline]
as_ref(&self) -> &[u8]111         fn as_ref(&self) -> &[u8] {
112             self.as_bytes()
113         }
114     }
115 
116     impl AsRef<BStr> for BString {
117         #[inline]
as_ref(&self) -> &BStr118         fn as_ref(&self) -> &BStr {
119             self.as_bstr()
120         }
121     }
122 
123     impl AsMut<[u8]> for BString {
124         #[inline]
as_mut(&mut self) -> &mut [u8]125         fn as_mut(&mut self) -> &mut [u8] {
126             self.as_bytes_mut()
127         }
128     }
129 
130     impl AsMut<BStr> for BString {
131         #[inline]
as_mut(&mut self) -> &mut BStr132         fn as_mut(&mut self) -> &mut BStr {
133             self.as_mut_bstr()
134         }
135     }
136 
137     impl Borrow<BStr> for BString {
138         #[inline]
borrow(&self) -> &BStr139         fn borrow(&self) -> &BStr {
140             self.as_bstr()
141         }
142     }
143 
144     impl ToOwned for BStr {
145         type Owned = BString;
146 
147         #[inline]
to_owned(&self) -> BString148         fn to_owned(&self) -> BString {
149             BString::from(self)
150         }
151     }
152 
153     impl Default for BString {
default() -> BString154         fn default() -> BString {
155             BString::from(vec![])
156         }
157     }
158 
159     impl<'a> From<&'a [u8]> for BString {
160         #[inline]
from(s: &'a [u8]) -> BString161         fn from(s: &'a [u8]) -> BString {
162             BString::from(s.to_vec())
163         }
164     }
165 
166     impl From<Vec<u8>> for BString {
167         #[inline]
from(s: Vec<u8>) -> BString168         fn from(s: Vec<u8>) -> BString {
169             BString::new(s)
170         }
171     }
172 
173     impl From<BString> for Vec<u8> {
174         #[inline]
from(s: BString) -> Vec<u8>175         fn from(s: BString) -> Vec<u8> {
176             s.into_vec()
177         }
178     }
179 
180     impl<'a> From<&'a str> for BString {
181         #[inline]
from(s: &'a str) -> BString182         fn from(s: &'a str) -> BString {
183             BString::from(s.as_bytes().to_vec())
184         }
185     }
186 
187     impl From<String> for BString {
188         #[inline]
from(s: String) -> BString189         fn from(s: String) -> BString {
190             BString::from(s.into_bytes())
191         }
192     }
193 
194     impl<'a> From<&'a BStr> for BString {
195         #[inline]
from(s: &'a BStr) -> BString196         fn from(s: &'a BStr) -> BString {
197             BString::from(s.bytes.to_vec())
198         }
199     }
200 
201     impl<'a> From<BString> for Cow<'a, BStr> {
202         #[inline]
from(s: BString) -> Cow<'a, BStr>203         fn from(s: BString) -> Cow<'a, BStr> {
204             Cow::Owned(s)
205         }
206     }
207 
208     impl TryFrom<BString> for String {
209         type Error = crate::FromUtf8Error;
210 
211         #[inline]
try_from(s: BString) -> Result<String, crate::FromUtf8Error>212         fn try_from(s: BString) -> Result<String, crate::FromUtf8Error> {
213             s.into_vec().into_string()
214         }
215     }
216 
217     impl<'a> TryFrom<&'a BString> for &'a str {
218         type Error = crate::Utf8Error;
219 
220         #[inline]
try_from(s: &'a BString) -> Result<&'a str, crate::Utf8Error>221         fn try_from(s: &'a BString) -> Result<&'a str, crate::Utf8Error> {
222             s.as_bytes().to_str()
223         }
224     }
225 
226     impl FromIterator<char> for BString {
227         #[inline]
from_iter<T: IntoIterator<Item = char>>(iter: T) -> BString228         fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> BString {
229             BString::from(iter.into_iter().collect::<String>())
230         }
231     }
232 
233     impl FromIterator<u8> for BString {
234         #[inline]
from_iter<T: IntoIterator<Item = u8>>(iter: T) -> BString235         fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> BString {
236             BString::from(iter.into_iter().collect::<Vec<u8>>())
237         }
238     }
239 
240     impl<'a> FromIterator<&'a str> for BString {
241         #[inline]
from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> BString242         fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> BString {
243             let mut buf = vec![];
244             for b in iter {
245                 buf.push_str(b);
246             }
247             BString::from(buf)
248         }
249     }
250 
251     impl<'a> FromIterator<&'a [u8]> for BString {
252         #[inline]
from_iter<T: IntoIterator<Item = &'a [u8]>>(iter: T) -> BString253         fn from_iter<T: IntoIterator<Item = &'a [u8]>>(iter: T) -> BString {
254             let mut buf = vec![];
255             for b in iter {
256                 buf.push_str(b);
257             }
258             BString::from(buf)
259         }
260     }
261 
262     impl<'a> FromIterator<&'a BStr> for BString {
263         #[inline]
from_iter<T: IntoIterator<Item = &'a BStr>>(iter: T) -> BString264         fn from_iter<T: IntoIterator<Item = &'a BStr>>(iter: T) -> BString {
265             let mut buf = vec![];
266             for b in iter {
267                 buf.push_str(b);
268             }
269             BString::from(buf)
270         }
271     }
272 
273     impl FromIterator<BString> for BString {
274         #[inline]
from_iter<T: IntoIterator<Item = BString>>(iter: T) -> BString275         fn from_iter<T: IntoIterator<Item = BString>>(iter: T) -> BString {
276             let mut buf = vec![];
277             for b in iter {
278                 buf.push_str(b);
279             }
280             BString::from(buf)
281         }
282     }
283 
284     impl Eq for BString {}
285 
286     impl PartialEq for BString {
287         #[inline]
eq(&self, other: &BString) -> bool288         fn eq(&self, other: &BString) -> bool {
289             &self[..] == &other[..]
290         }
291     }
292 
293     impl_partial_eq!(BString, Vec<u8>);
294     impl_partial_eq!(BString, [u8]);
295     impl_partial_eq!(BString, &'a [u8]);
296     impl_partial_eq!(BString, String);
297     impl_partial_eq!(BString, str);
298     impl_partial_eq!(BString, &'a str);
299     impl_partial_eq!(BString, BStr);
300     impl_partial_eq!(BString, &'a BStr);
301 
302     impl PartialOrd for BString {
303         #[inline]
partial_cmp(&self, other: &BString) -> Option<Ordering>304         fn partial_cmp(&self, other: &BString) -> Option<Ordering> {
305             PartialOrd::partial_cmp(self.as_bytes(), other.as_bytes())
306         }
307     }
308 
309     impl Ord for BString {
310         #[inline]
cmp(&self, other: &BString) -> Ordering311         fn cmp(&self, other: &BString) -> Ordering {
312             self.partial_cmp(other).unwrap()
313         }
314     }
315 
316     impl_partial_ord!(BString, Vec<u8>);
317     impl_partial_ord!(BString, [u8]);
318     impl_partial_ord!(BString, &'a [u8]);
319     impl_partial_ord!(BString, String);
320     impl_partial_ord!(BString, str);
321     impl_partial_ord!(BString, &'a str);
322     impl_partial_ord!(BString, BStr);
323     impl_partial_ord!(BString, &'a BStr);
324 }
325 
326 mod bstr {
327     use core::{cmp::Ordering, convert::TryFrom, fmt, ops};
328 
329     #[cfg(feature = "alloc")]
330     use alloc::{borrow::Cow, boxed::Box, string::String, vec::Vec};
331 
332     use crate::{bstr::BStr, ext_slice::ByteSlice};
333 
334     impl fmt::Display for BStr {
335         #[inline]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result336         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
337             /// Write the given bstr (lossily) to the given formatter.
338             fn write_bstr(
339                 f: &mut fmt::Formatter<'_>,
340                 bstr: &BStr,
341             ) -> Result<(), fmt::Error> {
342                 for chunk in bstr.utf8_chunks() {
343                     f.write_str(chunk.valid())?;
344                     if !chunk.invalid().is_empty() {
345                         f.write_str("\u{FFFD}")?;
346                     }
347                 }
348                 Ok(())
349             }
350 
351             /// Write 'num' fill characters to the given formatter.
352             fn write_pads(
353                 f: &mut fmt::Formatter<'_>,
354                 num: usize,
355             ) -> fmt::Result {
356                 let fill = f.fill();
357                 for _ in 0..num {
358                     f.write_fmt(format_args!("{}", fill))?;
359                 }
360                 Ok(())
361             }
362 
363             if let Some(align) = f.align() {
364                 let width = f.width().unwrap_or(0);
365                 let nchars = self.chars().count();
366                 let remaining_pads = width.saturating_sub(nchars);
367                 match align {
368                     fmt::Alignment::Left => {
369                         write_bstr(f, self)?;
370                         write_pads(f, remaining_pads)?;
371                     }
372                     fmt::Alignment::Right => {
373                         write_pads(f, remaining_pads)?;
374                         write_bstr(f, self)?;
375                     }
376                     fmt::Alignment::Center => {
377                         let half = remaining_pads / 2;
378                         let second_half = if remaining_pads % 2 == 0 {
379                             half
380                         } else {
381                             half + 1
382                         };
383                         write_pads(f, half)?;
384                         write_bstr(f, self)?;
385                         write_pads(f, second_half)?;
386                     }
387                 }
388                 Ok(())
389             } else {
390                 write_bstr(f, self)?;
391                 Ok(())
392             }
393         }
394     }
395 
396     impl fmt::Debug for BStr {
397         #[inline]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result398         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
399             write!(f, "\"")?;
400             for (s, e, ch) in self.char_indices() {
401                 match ch {
402                     '\0' => write!(f, "\\0")?,
403                     '\u{FFFD}' => {
404                         let bytes = self[s..e].as_bytes();
405                         if bytes == b"\xEF\xBF\xBD" {
406                             write!(f, "{}", ch.escape_debug())?;
407                         } else {
408                             for &b in self[s..e].as_bytes() {
409                                 write!(f, r"\x{:02X}", b)?;
410                             }
411                         }
412                     }
413                     // ASCII control characters except \0, \n, \r, \t
414                     '\x01'..='\x08'
415                     | '\x0b'
416                     | '\x0c'
417                     | '\x0e'..='\x19'
418                     | '\x7f' => {
419                         write!(f, "\\x{:02x}", ch as u32)?;
420                     }
421                     '\n' | '\r' | '\t' | _ => {
422                         write!(f, "{}", ch.escape_debug())?;
423                     }
424                 }
425             }
426             write!(f, "\"")?;
427             Ok(())
428         }
429     }
430 
431     impl ops::Deref for BStr {
432         type Target = [u8];
433 
434         #[inline]
deref(&self) -> &[u8]435         fn deref(&self) -> &[u8] {
436             &self.bytes
437         }
438     }
439 
440     impl ops::DerefMut for BStr {
441         #[inline]
deref_mut(&mut self) -> &mut [u8]442         fn deref_mut(&mut self) -> &mut [u8] {
443             &mut self.bytes
444         }
445     }
446 
447     impl ops::Index<usize> for BStr {
448         type Output = u8;
449 
450         #[inline]
index(&self, idx: usize) -> &u8451         fn index(&self, idx: usize) -> &u8 {
452             &self.as_bytes()[idx]
453         }
454     }
455 
456     impl ops::Index<ops::RangeFull> for BStr {
457         type Output = BStr;
458 
459         #[inline]
index(&self, _: ops::RangeFull) -> &BStr460         fn index(&self, _: ops::RangeFull) -> &BStr {
461             self
462         }
463     }
464 
465     impl ops::Index<ops::Range<usize>> for BStr {
466         type Output = BStr;
467 
468         #[inline]
index(&self, r: ops::Range<usize>) -> &BStr469         fn index(&self, r: ops::Range<usize>) -> &BStr {
470             BStr::new(&self.as_bytes()[r.start..r.end])
471         }
472     }
473 
474     impl ops::Index<ops::RangeInclusive<usize>> for BStr {
475         type Output = BStr;
476 
477         #[inline]
index(&self, r: ops::RangeInclusive<usize>) -> &BStr478         fn index(&self, r: ops::RangeInclusive<usize>) -> &BStr {
479             BStr::new(&self.as_bytes()[*r.start()..=*r.end()])
480         }
481     }
482 
483     impl ops::Index<ops::RangeFrom<usize>> for BStr {
484         type Output = BStr;
485 
486         #[inline]
index(&self, r: ops::RangeFrom<usize>) -> &BStr487         fn index(&self, r: ops::RangeFrom<usize>) -> &BStr {
488             BStr::new(&self.as_bytes()[r.start..])
489         }
490     }
491 
492     impl ops::Index<ops::RangeTo<usize>> for BStr {
493         type Output = BStr;
494 
495         #[inline]
index(&self, r: ops::RangeTo<usize>) -> &BStr496         fn index(&self, r: ops::RangeTo<usize>) -> &BStr {
497             BStr::new(&self.as_bytes()[..r.end])
498         }
499     }
500 
501     impl ops::Index<ops::RangeToInclusive<usize>> for BStr {
502         type Output = BStr;
503 
504         #[inline]
index(&self, r: ops::RangeToInclusive<usize>) -> &BStr505         fn index(&self, r: ops::RangeToInclusive<usize>) -> &BStr {
506             BStr::new(&self.as_bytes()[..=r.end])
507         }
508     }
509 
510     impl ops::IndexMut<usize> for BStr {
511         #[inline]
index_mut(&mut self, idx: usize) -> &mut u8512         fn index_mut(&mut self, idx: usize) -> &mut u8 {
513             &mut self.bytes[idx]
514         }
515     }
516 
517     impl ops::IndexMut<ops::RangeFull> for BStr {
518         #[inline]
index_mut(&mut self, _: ops::RangeFull) -> &mut BStr519         fn index_mut(&mut self, _: ops::RangeFull) -> &mut BStr {
520             self
521         }
522     }
523 
524     impl ops::IndexMut<ops::Range<usize>> for BStr {
525         #[inline]
index_mut(&mut self, r: ops::Range<usize>) -> &mut BStr526         fn index_mut(&mut self, r: ops::Range<usize>) -> &mut BStr {
527             BStr::from_bytes_mut(&mut self.bytes[r.start..r.end])
528         }
529     }
530 
531     impl ops::IndexMut<ops::RangeInclusive<usize>> for BStr {
532         #[inline]
index_mut(&mut self, r: ops::RangeInclusive<usize>) -> &mut BStr533         fn index_mut(&mut self, r: ops::RangeInclusive<usize>) -> &mut BStr {
534             BStr::from_bytes_mut(&mut self.bytes[*r.start()..=*r.end()])
535         }
536     }
537 
538     impl ops::IndexMut<ops::RangeFrom<usize>> for BStr {
539         #[inline]
index_mut(&mut self, r: ops::RangeFrom<usize>) -> &mut BStr540         fn index_mut(&mut self, r: ops::RangeFrom<usize>) -> &mut BStr {
541             BStr::from_bytes_mut(&mut self.bytes[r.start..])
542         }
543     }
544 
545     impl ops::IndexMut<ops::RangeTo<usize>> for BStr {
546         #[inline]
index_mut(&mut self, r: ops::RangeTo<usize>) -> &mut BStr547         fn index_mut(&mut self, r: ops::RangeTo<usize>) -> &mut BStr {
548             BStr::from_bytes_mut(&mut self.bytes[..r.end])
549         }
550     }
551 
552     impl ops::IndexMut<ops::RangeToInclusive<usize>> for BStr {
553         #[inline]
index_mut(&mut self, r: ops::RangeToInclusive<usize>) -> &mut BStr554         fn index_mut(&mut self, r: ops::RangeToInclusive<usize>) -> &mut BStr {
555             BStr::from_bytes_mut(&mut self.bytes[..=r.end])
556         }
557     }
558 
559     impl AsRef<[u8]> for BStr {
560         #[inline]
as_ref(&self) -> &[u8]561         fn as_ref(&self) -> &[u8] {
562             self.as_bytes()
563         }
564     }
565 
566     impl AsRef<BStr> for BStr {
567         #[inline]
as_ref(&self) -> &BStr568         fn as_ref(&self) -> &BStr {
569             self
570         }
571     }
572 
573     impl AsRef<BStr> for [u8] {
574         #[inline]
as_ref(&self) -> &BStr575         fn as_ref(&self) -> &BStr {
576             BStr::new(self)
577         }
578     }
579 
580     impl AsRef<BStr> for str {
581         #[inline]
as_ref(&self) -> &BStr582         fn as_ref(&self) -> &BStr {
583             BStr::new(self)
584         }
585     }
586 
587     impl AsMut<[u8]> for BStr {
588         #[inline]
as_mut(&mut self) -> &mut [u8]589         fn as_mut(&mut self) -> &mut [u8] {
590             &mut self.bytes
591         }
592     }
593 
594     impl AsMut<BStr> for [u8] {
595         #[inline]
as_mut(&mut self) -> &mut BStr596         fn as_mut(&mut self) -> &mut BStr {
597             BStr::new_mut(self)
598         }
599     }
600 
601     impl<'a> Default for &'a BStr {
default() -> &'a BStr602         fn default() -> &'a BStr {
603             BStr::from_bytes(b"")
604         }
605     }
606 
607     impl<'a> Default for &'a mut BStr {
default() -> &'a mut BStr608         fn default() -> &'a mut BStr {
609             BStr::from_bytes_mut(&mut [])
610         }
611     }
612 
613     impl<'a> From<&'a [u8]> for &'a BStr {
614         #[inline]
from(s: &'a [u8]) -> &'a BStr615         fn from(s: &'a [u8]) -> &'a BStr {
616             BStr::from_bytes(s)
617         }
618     }
619 
620     impl<'a> From<&'a BStr> for &'a [u8] {
621         #[inline]
from(s: &'a BStr) -> &'a [u8]622         fn from(s: &'a BStr) -> &'a [u8] {
623             BStr::as_bytes(s)
624         }
625     }
626 
627     impl<'a> From<&'a str> for &'a BStr {
628         #[inline]
from(s: &'a str) -> &'a BStr629         fn from(s: &'a str) -> &'a BStr {
630             BStr::from_bytes(s.as_bytes())
631         }
632     }
633 
634     #[cfg(feature = "alloc")]
635     impl<'a> From<&'a BStr> for Cow<'a, BStr> {
636         #[inline]
from(s: &'a BStr) -> Cow<'a, BStr>637         fn from(s: &'a BStr) -> Cow<'a, BStr> {
638             Cow::Borrowed(s)
639         }
640     }
641 
642     #[cfg(feature = "alloc")]
643     impl From<Box<[u8]>> for Box<BStr> {
644         #[inline]
from(s: Box<[u8]>) -> Box<BStr>645         fn from(s: Box<[u8]>) -> Box<BStr> {
646             BStr::from_boxed_bytes(s)
647         }
648     }
649 
650     #[cfg(feature = "alloc")]
651     impl From<Box<BStr>> for Box<[u8]> {
652         #[inline]
from(s: Box<BStr>) -> Box<[u8]>653         fn from(s: Box<BStr>) -> Box<[u8]> {
654             BStr::into_boxed_bytes(s)
655         }
656     }
657 
658     impl<'a> TryFrom<&'a BStr> for &'a str {
659         type Error = crate::Utf8Error;
660 
661         #[inline]
try_from(s: &'a BStr) -> Result<&'a str, crate::Utf8Error>662         fn try_from(s: &'a BStr) -> Result<&'a str, crate::Utf8Error> {
663             s.as_bytes().to_str()
664         }
665     }
666 
667     #[cfg(feature = "alloc")]
668     impl<'a> TryFrom<&'a BStr> for String {
669         type Error = crate::Utf8Error;
670 
671         #[inline]
try_from(s: &'a BStr) -> Result<String, crate::Utf8Error>672         fn try_from(s: &'a BStr) -> Result<String, crate::Utf8Error> {
673             Ok(s.as_bytes().to_str()?.into())
674         }
675     }
676 
677     #[cfg(feature = "alloc")]
678     impl Clone for Box<BStr> {
679         #[inline]
clone(&self) -> Self680         fn clone(&self) -> Self {
681             BStr::from_boxed_bytes(self.as_bytes().into())
682         }
683     }
684 
685     impl Eq for BStr {}
686 
687     impl PartialEq<BStr> for BStr {
688         #[inline]
eq(&self, other: &BStr) -> bool689         fn eq(&self, other: &BStr) -> bool {
690             self.as_bytes() == other.as_bytes()
691         }
692     }
693 
694     impl_partial_eq!(BStr, [u8]);
695     impl_partial_eq!(BStr, &'a [u8]);
696     impl_partial_eq!(BStr, str);
697     impl_partial_eq!(BStr, &'a str);
698 
699     #[cfg(feature = "alloc")]
700     impl_partial_eq!(BStr, Vec<u8>);
701     #[cfg(feature = "alloc")]
702     impl_partial_eq!(&'a BStr, Vec<u8>);
703     #[cfg(feature = "alloc")]
704     impl_partial_eq!(BStr, String);
705     #[cfg(feature = "alloc")]
706     impl_partial_eq!(&'a BStr, String);
707     #[cfg(feature = "alloc")]
708     impl_partial_eq_cow!(&'a BStr, Cow<'a, BStr>);
709     #[cfg(feature = "alloc")]
710     impl_partial_eq_cow!(&'a BStr, Cow<'a, str>);
711     #[cfg(feature = "alloc")]
712     impl_partial_eq_cow!(&'a BStr, Cow<'a, [u8]>);
713 
714     impl PartialOrd for BStr {
715         #[inline]
partial_cmp(&self, other: &BStr) -> Option<Ordering>716         fn partial_cmp(&self, other: &BStr) -> Option<Ordering> {
717             PartialOrd::partial_cmp(self.as_bytes(), other.as_bytes())
718         }
719     }
720 
721     impl Ord for BStr {
722         #[inline]
cmp(&self, other: &BStr) -> Ordering723         fn cmp(&self, other: &BStr) -> Ordering {
724             self.partial_cmp(other).unwrap()
725         }
726     }
727 
728     impl_partial_ord!(BStr, [u8]);
729     impl_partial_ord!(BStr, &'a [u8]);
730     impl_partial_ord!(BStr, str);
731     impl_partial_ord!(BStr, &'a str);
732 
733     #[cfg(feature = "alloc")]
734     impl_partial_ord!(BStr, Vec<u8>);
735     #[cfg(feature = "alloc")]
736     impl_partial_ord!(&'a BStr, Vec<u8>);
737     #[cfg(feature = "alloc")]
738     impl_partial_ord!(BStr, String);
739     #[cfg(feature = "alloc")]
740     impl_partial_ord!(&'a BStr, String);
741 }
742 
743 #[cfg(feature = "serde")]
744 mod bstr_serde {
745     use core::fmt;
746 
747     use serde::{
748         de::Error, de::Visitor, Deserialize, Deserializer, Serialize,
749         Serializer,
750     };
751 
752     use crate::bstr::BStr;
753 
754     impl Serialize for BStr {
755         #[inline]
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,756         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
757         where
758             S: Serializer,
759         {
760             serializer.serialize_bytes(self.as_bytes())
761         }
762     }
763 
764     impl<'a, 'de: 'a> Deserialize<'de> for &'a BStr {
765         #[inline]
deserialize<D>(deserializer: D) -> Result<&'a BStr, D::Error> where D: Deserializer<'de>,766         fn deserialize<D>(deserializer: D) -> Result<&'a BStr, D::Error>
767         where
768             D: Deserializer<'de>,
769         {
770             struct BStrVisitor;
771 
772             impl<'de> Visitor<'de> for BStrVisitor {
773                 type Value = &'de BStr;
774 
775                 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
776                     f.write_str("a borrowed byte string")
777                 }
778 
779                 #[inline]
780                 fn visit_borrowed_bytes<E: Error>(
781                     self,
782                     value: &'de [u8],
783                 ) -> Result<&'de BStr, E> {
784                     Ok(BStr::new(value))
785                 }
786 
787                 #[inline]
788                 fn visit_borrowed_str<E: Error>(
789                     self,
790                     value: &'de str,
791                 ) -> Result<&'de BStr, E> {
792                     Ok(BStr::new(value))
793                 }
794             }
795 
796             deserializer.deserialize_bytes(BStrVisitor)
797         }
798     }
799 }
800 
801 #[cfg(all(feature = "serde", feature = "alloc"))]
802 mod bstring_serde {
803     use core::{cmp, fmt};
804 
805     use alloc::{boxed::Box, string::String, vec::Vec};
806 
807     use serde::{
808         de::Error, de::SeqAccess, de::Visitor, Deserialize, Deserializer,
809         Serialize, Serializer,
810     };
811 
812     use crate::{bstr::BStr, bstring::BString};
813 
814     impl Serialize for BString {
815         #[inline]
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,816         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
817         where
818             S: Serializer,
819         {
820             serializer.serialize_bytes(self.as_bytes())
821         }
822     }
823 
824     impl<'de> Deserialize<'de> for BString {
825         #[inline]
deserialize<D>(deserializer: D) -> Result<BString, D::Error> where D: Deserializer<'de>,826         fn deserialize<D>(deserializer: D) -> Result<BString, D::Error>
827         where
828             D: Deserializer<'de>,
829         {
830             struct BStringVisitor;
831 
832             impl<'de> Visitor<'de> for BStringVisitor {
833                 type Value = BString;
834 
835                 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
836                     f.write_str("a byte string")
837                 }
838 
839                 #[inline]
840                 fn visit_seq<V: SeqAccess<'de>>(
841                     self,
842                     mut visitor: V,
843                 ) -> Result<BString, V::Error> {
844                     let len = cmp::min(visitor.size_hint().unwrap_or(0), 256);
845                     let mut bytes = Vec::with_capacity(len);
846                     while let Some(v) = visitor.next_element()? {
847                         bytes.push(v);
848                     }
849                     Ok(BString::from(bytes))
850                 }
851 
852                 #[inline]
853                 fn visit_bytes<E: Error>(
854                     self,
855                     value: &[u8],
856                 ) -> Result<BString, E> {
857                     Ok(BString::from(value))
858                 }
859 
860                 #[inline]
861                 fn visit_byte_buf<E: Error>(
862                     self,
863                     value: Vec<u8>,
864                 ) -> Result<BString, E> {
865                     Ok(BString::from(value))
866                 }
867 
868                 #[inline]
869                 fn visit_str<E: Error>(
870                     self,
871                     value: &str,
872                 ) -> Result<BString, E> {
873                     Ok(BString::from(value))
874                 }
875 
876                 #[inline]
877                 fn visit_string<E: Error>(
878                     self,
879                     value: String,
880                 ) -> Result<BString, E> {
881                     Ok(BString::from(value))
882                 }
883             }
884 
885             deserializer.deserialize_byte_buf(BStringVisitor)
886         }
887     }
888 
889     impl<'de> Deserialize<'de> for Box<BStr> {
890         #[inline]
deserialize<D>(deserializer: D) -> Result<Box<BStr>, D::Error> where D: Deserializer<'de>,891         fn deserialize<D>(deserializer: D) -> Result<Box<BStr>, D::Error>
892         where
893             D: Deserializer<'de>,
894         {
895             struct BoxedBStrVisitor;
896 
897             impl<'de> Visitor<'de> for BoxedBStrVisitor {
898                 type Value = Box<BStr>;
899 
900                 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
901                     f.write_str("a boxed byte string")
902                 }
903 
904                 #[inline]
905                 fn visit_seq<V: SeqAccess<'de>>(
906                     self,
907                     mut visitor: V,
908                 ) -> Result<Box<BStr>, V::Error> {
909                     let len = cmp::min(visitor.size_hint().unwrap_or(0), 256);
910                     let mut bytes = Vec::with_capacity(len);
911                     while let Some(v) = visitor.next_element()? {
912                         bytes.push(v);
913                     }
914                     Ok(BStr::from_boxed_bytes(bytes.into_boxed_slice()))
915                 }
916 
917                 #[inline]
918                 fn visit_bytes<E: Error>(
919                     self,
920                     value: &[u8],
921                 ) -> Result<Box<BStr>, E> {
922                     Ok(BStr::from_boxed_bytes(
923                         value.to_vec().into_boxed_slice(),
924                     ))
925                 }
926 
927                 #[inline]
928                 fn visit_byte_buf<E: Error>(
929                     self,
930                     value: Vec<u8>,
931                 ) -> Result<Box<BStr>, E> {
932                     Ok(BStr::from_boxed_bytes(value.into_boxed_slice()))
933                 }
934 
935                 #[inline]
936                 fn visit_str<E: Error>(
937                     self,
938                     value: &str,
939                 ) -> Result<Box<BStr>, E> {
940                     Ok(BStr::from_boxed_bytes(
941                         value.as_bytes().to_vec().into_boxed_slice(),
942                     ))
943                 }
944 
945                 #[inline]
946                 fn visit_string<E: Error>(
947                     self,
948                     value: String,
949                 ) -> Result<Box<BStr>, E> {
950                     Ok(BStr::from_boxed_bytes(
951                         value.into_bytes().into_boxed_slice(),
952                     ))
953                 }
954             }
955 
956             deserializer.deserialize_byte_buf(BoxedBStrVisitor)
957         }
958     }
959 }
960 
961 #[cfg(all(test, feature = "std"))]
962 mod display {
963     #[cfg(not(miri))]
964     use crate::bstring::BString;
965     use crate::ByteSlice;
966 
967     #[test]
clean()968     fn clean() {
969         assert_eq!(&format!("{}", &b"abc".as_bstr()), "abc");
970         assert_eq!(&format!("{}", &b"\xf0\x28\x8c\xbc".as_bstr()), "�(��");
971     }
972 
973     #[test]
width_bigger_than_bstr()974     fn width_bigger_than_bstr() {
975         assert_eq!(&format!("{:<7}!", &b"abc".as_bstr()), "abc    !");
976         assert_eq!(&format!("{:>7}!", &b"abc".as_bstr()), "    abc!");
977         assert_eq!(&format!("{:^7}!", &b"abc".as_bstr()), "  abc  !");
978         assert_eq!(&format!("{:^6}!", &b"abc".as_bstr()), " abc  !");
979         assert_eq!(&format!("{:-<7}!", &b"abc".as_bstr()), "abc----!");
980         assert_eq!(&format!("{:->7}!", &b"abc".as_bstr()), "----abc!");
981         assert_eq!(&format!("{:-^7}!", &b"abc".as_bstr()), "--abc--!");
982         assert_eq!(&format!("{:-^6}!", &b"abc".as_bstr()), "-abc--!");
983 
984         assert_eq!(
985             &format!("{:<7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
986             "�(��   !"
987         );
988         assert_eq!(
989             &format!("{:>7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
990             "   �(��!"
991         );
992         assert_eq!(
993             &format!("{:^7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
994             " �(��  !"
995         );
996         assert_eq!(
997             &format!("{:^6}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
998             " �(�� !"
999         );
1000 
1001         assert_eq!(
1002             &format!("{:-<7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1003             "�(��---!"
1004         );
1005         assert_eq!(
1006             &format!("{:->7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1007             "---�(��!"
1008         );
1009         assert_eq!(
1010             &format!("{:-^7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1011             "-�(��--!"
1012         );
1013         assert_eq!(
1014             &format!("{:-^6}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1015             "-�(��-!"
1016         );
1017     }
1018 
1019     #[test]
width_lesser_than_bstr()1020     fn width_lesser_than_bstr() {
1021         assert_eq!(&format!("{:<2}!", &b"abc".as_bstr()), "abc!");
1022         assert_eq!(&format!("{:>2}!", &b"abc".as_bstr()), "abc!");
1023         assert_eq!(&format!("{:^2}!", &b"abc".as_bstr()), "abc!");
1024         assert_eq!(&format!("{:-<2}!", &b"abc".as_bstr()), "abc!");
1025         assert_eq!(&format!("{:->2}!", &b"abc".as_bstr()), "abc!");
1026         assert_eq!(&format!("{:-^2}!", &b"abc".as_bstr()), "abc!");
1027 
1028         assert_eq!(
1029             &format!("{:<3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1030             "�(��!"
1031         );
1032         assert_eq!(
1033             &format!("{:>3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1034             "�(��!"
1035         );
1036         assert_eq!(
1037             &format!("{:^3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1038             "�(��!"
1039         );
1040         assert_eq!(
1041             &format!("{:^2}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1042             "�(��!"
1043         );
1044 
1045         assert_eq!(
1046             &format!("{:-<3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1047             "�(��!"
1048         );
1049         assert_eq!(
1050             &format!("{:->3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1051             "�(��!"
1052         );
1053         assert_eq!(
1054             &format!("{:-^3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1055             "�(��!"
1056         );
1057         assert_eq!(
1058             &format!("{:-^2}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1059             "�(��!"
1060         );
1061     }
1062 
1063     #[cfg(not(miri))]
1064     quickcheck::quickcheck! {
1065         fn total_length(bstr: BString) -> bool {
1066             let size = bstr.chars().count();
1067             format!("{:<1$}", bstr.as_bstr(), size).chars().count() >= size
1068         }
1069     }
1070 }
1071 
1072 #[cfg(all(test, feature = "alloc"))]
1073 mod bstring_arbitrary {
1074     use crate::bstring::BString;
1075 
1076     use quickcheck::{Arbitrary, Gen};
1077 
1078     impl Arbitrary for BString {
arbitrary(g: &mut Gen) -> BString1079         fn arbitrary(g: &mut Gen) -> BString {
1080             BString::from(Vec::<u8>::arbitrary(g))
1081         }
1082 
shrink(&self) -> Box<dyn Iterator<Item = BString>>1083         fn shrink(&self) -> Box<dyn Iterator<Item = BString>> {
1084             Box::new(self.as_vec().shrink().map(BString::from))
1085         }
1086     }
1087 }
1088 
1089 #[test]
1090 #[cfg(feature = "std")]
test_debug()1091 fn test_debug() {
1092     use crate::{ByteSlice, B};
1093 
1094     assert_eq!(
1095         r#""\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp""#,
1096         format!("{:?}", b"\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp".as_bstr()),
1097     );
1098 
1099     // Tests that if the underlying bytes contain the UTF-8 encoding of the
1100     // replacement codepoint, then we emit the codepoint just like other
1101     // non-printable Unicode characters.
1102     assert_eq!(
1103         b"\"\\xFF\xEF\xBF\xBD\\xFF\"".as_bstr(),
1104         // Before fixing #72, the output here would be:
1105         //   \\xFF\\xEF\\xBF\\xBD\\xFF
1106         B(&format!("{:?}", b"\xFF\xEF\xBF\xBD\xFF".as_bstr())).as_bstr(),
1107     );
1108 }
1109 
1110 // See: https://github.com/BurntSushi/bstr/issues/82
1111 #[test]
1112 #[cfg(feature = "std")]
test_cows_regression()1113 fn test_cows_regression() {
1114     use std::borrow::Cow;
1115 
1116     use crate::ByteSlice;
1117 
1118     let c1 = Cow::from(b"hello bstr".as_bstr());
1119     let c2 = b"goodbye bstr".as_bstr();
1120     assert_ne!(c1, c2);
1121 
1122     let c3 = Cow::from("hello str");
1123     let c4 = "goodbye str";
1124     assert_ne!(c3, c4);
1125 }
1126