bstr/
impls.rs

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