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 = "std")]
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 = "std")]
63 mod bstring {
64     use std::borrow::{Borrow, Cow, ToOwned};
65     use std::cmp::Ordering;
66     use std::fmt;
67     use std::iter::FromIterator;
68     use std::ops;
69 
70     use crate::bstr::BStr;
71     use crate::bstring::BString;
72     use crate::ext_vec::ByteVec;
73 
74     impl fmt::Display for BString {
75         #[inline]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result76         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77             fmt::Display::fmt(self.as_bstr(), f)
78         }
79     }
80 
81     impl fmt::Debug for BString {
82         #[inline]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result83         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84             fmt::Debug::fmt(self.as_bstr(), f)
85         }
86     }
87 
88     impl ops::Deref for BString {
89         type Target = Vec<u8>;
90 
91         #[inline]
deref(&self) -> &Vec<u8>92         fn deref(&self) -> &Vec<u8> {
93             &self.bytes
94         }
95     }
96 
97     impl ops::DerefMut for BString {
98         #[inline]
deref_mut(&mut self) -> &mut Vec<u8>99         fn deref_mut(&mut self) -> &mut Vec<u8> {
100             &mut self.bytes
101         }
102     }
103 
104     impl AsRef<[u8]> for BString {
105         #[inline]
as_ref(&self) -> &[u8]106         fn as_ref(&self) -> &[u8] {
107             &self.bytes
108         }
109     }
110 
111     impl AsRef<BStr> for BString {
112         #[inline]
as_ref(&self) -> &BStr113         fn as_ref(&self) -> &BStr {
114             self.as_bstr()
115         }
116     }
117 
118     impl AsMut<[u8]> for BString {
119         #[inline]
as_mut(&mut self) -> &mut [u8]120         fn as_mut(&mut self) -> &mut [u8] {
121             &mut self.bytes
122         }
123     }
124 
125     impl AsMut<BStr> for BString {
126         #[inline]
as_mut(&mut self) -> &mut BStr127         fn as_mut(&mut self) -> &mut BStr {
128             self.as_mut_bstr()
129         }
130     }
131 
132     impl Borrow<BStr> for BString {
133         #[inline]
borrow(&self) -> &BStr134         fn borrow(&self) -> &BStr {
135             self.as_bstr()
136         }
137     }
138 
139     impl ToOwned for BStr {
140         type Owned = BString;
141 
142         #[inline]
to_owned(&self) -> BString143         fn to_owned(&self) -> BString {
144             BString::from(self)
145         }
146     }
147 
148     impl Default for BString {
default() -> BString149         fn default() -> BString {
150             BString::from(vec![])
151         }
152     }
153 
154     impl<'a> From<&'a [u8]> for BString {
155         #[inline]
from(s: &'a [u8]) -> BString156         fn from(s: &'a [u8]) -> BString {
157             BString::from(s.to_vec())
158         }
159     }
160 
161     impl From<Vec<u8>> for BString {
162         #[inline]
from(s: Vec<u8>) -> BString163         fn from(s: Vec<u8>) -> BString {
164             BString { bytes: s }
165         }
166     }
167 
168     impl From<BString> for Vec<u8> {
169         #[inline]
from(s: BString) -> Vec<u8>170         fn from(s: BString) -> Vec<u8> {
171             s.bytes
172         }
173     }
174 
175     impl<'a> From<&'a str> for BString {
176         #[inline]
from(s: &'a str) -> BString177         fn from(s: &'a str) -> BString {
178             BString::from(s.as_bytes().to_vec())
179         }
180     }
181 
182     impl From<String> for BString {
183         #[inline]
from(s: String) -> BString184         fn from(s: String) -> BString {
185             BString::from(s.into_bytes())
186         }
187     }
188 
189     impl<'a> From<&'a BStr> for BString {
190         #[inline]
from(s: &'a BStr) -> BString191         fn from(s: &'a BStr) -> BString {
192             BString::from(s.bytes.to_vec())
193         }
194     }
195 
196     impl<'a> From<BString> for Cow<'a, BStr> {
197         #[inline]
from(s: BString) -> Cow<'a, BStr>198         fn from(s: BString) -> Cow<'a, BStr> {
199             Cow::Owned(s)
200         }
201     }
202 
203     impl FromIterator<char> for BString {
204         #[inline]
from_iter<T: IntoIterator<Item = char>>(iter: T) -> BString205         fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> BString {
206             BString::from(iter.into_iter().collect::<String>())
207         }
208     }
209 
210     impl FromIterator<u8> for BString {
211         #[inline]
from_iter<T: IntoIterator<Item = u8>>(iter: T) -> BString212         fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> BString {
213             BString::from(iter.into_iter().collect::<Vec<u8>>())
214         }
215     }
216 
217     impl<'a> FromIterator<&'a str> for BString {
218         #[inline]
from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> BString219         fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> BString {
220             let mut buf = vec![];
221             for b in iter {
222                 buf.push_str(b);
223             }
224             BString::from(buf)
225         }
226     }
227 
228     impl<'a> FromIterator<&'a [u8]> for BString {
229         #[inline]
from_iter<T: IntoIterator<Item = &'a [u8]>>(iter: T) -> BString230         fn from_iter<T: IntoIterator<Item = &'a [u8]>>(iter: T) -> BString {
231             let mut buf = vec![];
232             for b in iter {
233                 buf.push_str(b);
234             }
235             BString::from(buf)
236         }
237     }
238 
239     impl<'a> FromIterator<&'a BStr> for BString {
240         #[inline]
from_iter<T: IntoIterator<Item = &'a BStr>>(iter: T) -> BString241         fn from_iter<T: IntoIterator<Item = &'a BStr>>(iter: T) -> BString {
242             let mut buf = vec![];
243             for b in iter {
244                 buf.push_str(b);
245             }
246             BString::from(buf)
247         }
248     }
249 
250     impl FromIterator<BString> for BString {
251         #[inline]
from_iter<T: IntoIterator<Item = BString>>(iter: T) -> BString252         fn from_iter<T: IntoIterator<Item = BString>>(iter: T) -> BString {
253             let mut buf = vec![];
254             for b in iter {
255                 buf.push_str(b);
256             }
257             BString::from(buf)
258         }
259     }
260 
261     impl Eq for BString {}
262 
263     impl PartialEq for BString {
264         #[inline]
eq(&self, other: &BString) -> bool265         fn eq(&self, other: &BString) -> bool {
266             &self[..] == &other[..]
267         }
268     }
269 
270     impl_partial_eq!(BString, Vec<u8>);
271     impl_partial_eq!(BString, [u8]);
272     impl_partial_eq!(BString, &'a [u8]);
273     impl_partial_eq!(BString, String);
274     impl_partial_eq!(BString, str);
275     impl_partial_eq!(BString, &'a str);
276     impl_partial_eq!(BString, BStr);
277     impl_partial_eq!(BString, &'a BStr);
278 
279     impl PartialOrd for BString {
280         #[inline]
partial_cmp(&self, other: &BString) -> Option<Ordering>281         fn partial_cmp(&self, other: &BString) -> Option<Ordering> {
282             PartialOrd::partial_cmp(&self.bytes, &other.bytes)
283         }
284     }
285 
286     impl Ord for BString {
287         #[inline]
cmp(&self, other: &BString) -> Ordering288         fn cmp(&self, other: &BString) -> Ordering {
289             self.partial_cmp(other).unwrap()
290         }
291     }
292 
293     impl_partial_ord!(BString, Vec<u8>);
294     impl_partial_ord!(BString, [u8]);
295     impl_partial_ord!(BString, &'a [u8]);
296     impl_partial_ord!(BString, String);
297     impl_partial_ord!(BString, str);
298     impl_partial_ord!(BString, &'a str);
299     impl_partial_ord!(BString, BStr);
300     impl_partial_ord!(BString, &'a BStr);
301 }
302 
303 mod bstr {
304     #[cfg(feature = "std")]
305     use std::borrow::Cow;
306 
307     use core::cmp::Ordering;
308     use core::fmt;
309     use core::ops;
310 
311     use crate::bstr::BStr;
312     use crate::ext_slice::ByteSlice;
313 
314     impl fmt::Display for BStr {
315         #[inline]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result316         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
317             /// Write the given bstr (lossily) to the given formatter.
318             fn write_bstr(
319                 f: &mut fmt::Formatter<'_>,
320                 bstr: &BStr,
321             ) -> Result<(), fmt::Error> {
322                 for chunk in bstr.utf8_chunks() {
323                     f.write_str(chunk.valid())?;
324                     if !chunk.invalid().is_empty() {
325                         f.write_str("\u{FFFD}")?;
326                     }
327                 }
328                 Ok(())
329             }
330 
331             /// Write 'num' fill characters to the given formatter.
332             fn write_pads(
333                 f: &mut fmt::Formatter<'_>,
334                 num: usize,
335             ) -> fmt::Result {
336                 let fill = f.fill();
337                 for _ in 0..num {
338                     f.write_fmt(format_args!("{}", fill))?;
339                 }
340                 Ok(())
341             }
342 
343             if let Some(align) = f.align() {
344                 let width = f.width().unwrap_or(0);
345                 let nchars = self.chars().count();
346                 let remaining_pads = width.saturating_sub(nchars);
347                 match align {
348                     fmt::Alignment::Left => {
349                         write_bstr(f, self)?;
350                         write_pads(f, remaining_pads)?;
351                     }
352                     fmt::Alignment::Right => {
353                         write_pads(f, remaining_pads)?;
354                         write_bstr(f, self)?;
355                     }
356                     fmt::Alignment::Center => {
357                         let half = remaining_pads / 2;
358                         let second_half = if remaining_pads % 2 == 0 {
359                             half
360                         } else {
361                             half + 1
362                         };
363                         write_pads(f, half)?;
364                         write_bstr(f, self)?;
365                         write_pads(f, second_half)?;
366                     }
367                 }
368                 Ok(())
369             } else {
370                 write_bstr(f, self)?;
371                 Ok(())
372             }
373         }
374     }
375 
376     impl fmt::Debug for BStr {
377         #[inline]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result378         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
379             write!(f, "\"")?;
380             for (s, e, ch) in self.char_indices() {
381                 match ch {
382                     '\0' => write!(f, "\\0")?,
383                     '\u{FFFD}' => {
384                         let bytes = self[s..e].as_bytes();
385                         if bytes == b"\xEF\xBF\xBD" {
386                             write!(f, "{}", ch.escape_debug())?;
387                         } else {
388                             for &b in self[s..e].as_bytes() {
389                                 write!(f, r"\x{:02X}", b)?;
390                             }
391                         }
392                     }
393                     // ASCII control characters except \0, \n, \r, \t
394                     '\x01'..='\x08'
395                     | '\x0b'
396                     | '\x0c'
397                     | '\x0e'..='\x19'
398                     | '\x7f' => {
399                         write!(f, "\\x{:02x}", ch as u32)?;
400                     }
401                     '\n' | '\r' | '\t' | _ => {
402                         write!(f, "{}", ch.escape_debug())?;
403                     }
404                 }
405             }
406             write!(f, "\"")?;
407             Ok(())
408         }
409     }
410 
411     impl ops::Deref for BStr {
412         type Target = [u8];
413 
414         #[inline]
deref(&self) -> &[u8]415         fn deref(&self) -> &[u8] {
416             &self.bytes
417         }
418     }
419 
420     impl ops::DerefMut for BStr {
421         #[inline]
deref_mut(&mut self) -> &mut [u8]422         fn deref_mut(&mut self) -> &mut [u8] {
423             &mut self.bytes
424         }
425     }
426 
427     impl ops::Index<usize> for BStr {
428         type Output = u8;
429 
430         #[inline]
index(&self, idx: usize) -> &u8431         fn index(&self, idx: usize) -> &u8 {
432             &self.as_bytes()[idx]
433         }
434     }
435 
436     impl ops::Index<ops::RangeFull> for BStr {
437         type Output = BStr;
438 
439         #[inline]
index(&self, _: ops::RangeFull) -> &BStr440         fn index(&self, _: ops::RangeFull) -> &BStr {
441             self
442         }
443     }
444 
445     impl ops::Index<ops::Range<usize>> for BStr {
446         type Output = BStr;
447 
448         #[inline]
index(&self, r: ops::Range<usize>) -> &BStr449         fn index(&self, r: ops::Range<usize>) -> &BStr {
450             BStr::new(&self.as_bytes()[r.start..r.end])
451         }
452     }
453 
454     impl ops::Index<ops::RangeInclusive<usize>> for BStr {
455         type Output = BStr;
456 
457         #[inline]
index(&self, r: ops::RangeInclusive<usize>) -> &BStr458         fn index(&self, r: ops::RangeInclusive<usize>) -> &BStr {
459             BStr::new(&self.as_bytes()[*r.start()..=*r.end()])
460         }
461     }
462 
463     impl ops::Index<ops::RangeFrom<usize>> for BStr {
464         type Output = BStr;
465 
466         #[inline]
index(&self, r: ops::RangeFrom<usize>) -> &BStr467         fn index(&self, r: ops::RangeFrom<usize>) -> &BStr {
468             BStr::new(&self.as_bytes()[r.start..])
469         }
470     }
471 
472     impl ops::Index<ops::RangeTo<usize>> for BStr {
473         type Output = BStr;
474 
475         #[inline]
index(&self, r: ops::RangeTo<usize>) -> &BStr476         fn index(&self, r: ops::RangeTo<usize>) -> &BStr {
477             BStr::new(&self.as_bytes()[..r.end])
478         }
479     }
480 
481     impl ops::Index<ops::RangeToInclusive<usize>> for BStr {
482         type Output = BStr;
483 
484         #[inline]
index(&self, r: ops::RangeToInclusive<usize>) -> &BStr485         fn index(&self, r: ops::RangeToInclusive<usize>) -> &BStr {
486             BStr::new(&self.as_bytes()[..=r.end])
487         }
488     }
489 
490     impl ops::IndexMut<usize> for BStr {
491         #[inline]
index_mut(&mut self, idx: usize) -> &mut u8492         fn index_mut(&mut self, idx: usize) -> &mut u8 {
493             &mut self.bytes[idx]
494         }
495     }
496 
497     impl ops::IndexMut<ops::RangeFull> for BStr {
498         #[inline]
index_mut(&mut self, _: ops::RangeFull) -> &mut BStr499         fn index_mut(&mut self, _: ops::RangeFull) -> &mut BStr {
500             self
501         }
502     }
503 
504     impl ops::IndexMut<ops::Range<usize>> for BStr {
505         #[inline]
index_mut(&mut self, r: ops::Range<usize>) -> &mut BStr506         fn index_mut(&mut self, r: ops::Range<usize>) -> &mut BStr {
507             BStr::from_bytes_mut(&mut self.bytes[r.start..r.end])
508         }
509     }
510 
511     impl ops::IndexMut<ops::RangeInclusive<usize>> for BStr {
512         #[inline]
index_mut(&mut self, r: ops::RangeInclusive<usize>) -> &mut BStr513         fn index_mut(&mut self, r: ops::RangeInclusive<usize>) -> &mut BStr {
514             BStr::from_bytes_mut(&mut self.bytes[*r.start()..=*r.end()])
515         }
516     }
517 
518     impl ops::IndexMut<ops::RangeFrom<usize>> for BStr {
519         #[inline]
index_mut(&mut self, r: ops::RangeFrom<usize>) -> &mut BStr520         fn index_mut(&mut self, r: ops::RangeFrom<usize>) -> &mut BStr {
521             BStr::from_bytes_mut(&mut self.bytes[r.start..])
522         }
523     }
524 
525     impl ops::IndexMut<ops::RangeTo<usize>> for BStr {
526         #[inline]
index_mut(&mut self, r: ops::RangeTo<usize>) -> &mut BStr527         fn index_mut(&mut self, r: ops::RangeTo<usize>) -> &mut BStr {
528             BStr::from_bytes_mut(&mut self.bytes[..r.end])
529         }
530     }
531 
532     impl ops::IndexMut<ops::RangeToInclusive<usize>> for BStr {
533         #[inline]
index_mut(&mut self, r: ops::RangeToInclusive<usize>) -> &mut BStr534         fn index_mut(&mut self, r: ops::RangeToInclusive<usize>) -> &mut BStr {
535             BStr::from_bytes_mut(&mut self.bytes[..=r.end])
536         }
537     }
538 
539     impl AsRef<[u8]> for BStr {
540         #[inline]
as_ref(&self) -> &[u8]541         fn as_ref(&self) -> &[u8] {
542             self.as_bytes()
543         }
544     }
545 
546     impl AsRef<BStr> for [u8] {
547         #[inline]
as_ref(&self) -> &BStr548         fn as_ref(&self) -> &BStr {
549             BStr::new(self)
550         }
551     }
552 
553     impl AsRef<BStr> for str {
554         #[inline]
as_ref(&self) -> &BStr555         fn as_ref(&self) -> &BStr {
556             BStr::new(self)
557         }
558     }
559 
560     impl AsMut<[u8]> for BStr {
561         #[inline]
as_mut(&mut self) -> &mut [u8]562         fn as_mut(&mut self) -> &mut [u8] {
563             &mut self.bytes
564         }
565     }
566 
567     impl AsMut<BStr> for [u8] {
568         #[inline]
as_mut(&mut self) -> &mut BStr569         fn as_mut(&mut self) -> &mut BStr {
570             BStr::new_mut(self)
571         }
572     }
573 
574     impl<'a> Default for &'a BStr {
default() -> &'a BStr575         fn default() -> &'a BStr {
576             BStr::from_bytes(b"")
577         }
578     }
579 
580     impl<'a> Default for &'a mut BStr {
default() -> &'a mut BStr581         fn default() -> &'a mut BStr {
582             BStr::from_bytes_mut(&mut [])
583         }
584     }
585 
586     impl<'a> From<&'a [u8]> for &'a BStr {
587         #[inline]
from(s: &'a [u8]) -> &'a BStr588         fn from(s: &'a [u8]) -> &'a BStr {
589             BStr::from_bytes(s)
590         }
591     }
592 
593     impl<'a> From<&'a str> for &'a BStr {
594         #[inline]
from(s: &'a str) -> &'a BStr595         fn from(s: &'a str) -> &'a BStr {
596             BStr::from_bytes(s.as_bytes())
597         }
598     }
599 
600     #[cfg(feature = "std")]
601     impl<'a> From<&'a BStr> for Cow<'a, BStr> {
602         #[inline]
from(s: &'a BStr) -> Cow<'a, BStr>603         fn from(s: &'a BStr) -> Cow<'a, BStr> {
604             Cow::Borrowed(s)
605         }
606     }
607 
608     #[cfg(feature = "std")]
609     impl From<Box<[u8]>> for Box<BStr> {
610         #[inline]
from(s: Box<[u8]>) -> Box<BStr>611         fn from(s: Box<[u8]>) -> Box<BStr> {
612             BStr::from_boxed_bytes(s)
613         }
614     }
615 
616     #[cfg(feature = "std")]
617     impl From<Box<BStr>> for Box<[u8]> {
618         #[inline]
from(s: Box<BStr>) -> Box<[u8]>619         fn from(s: Box<BStr>) -> Box<[u8]> {
620             BStr::into_boxed_bytes(s)
621         }
622     }
623 
624     impl Eq for BStr {}
625 
626     impl PartialEq<BStr> for BStr {
627         #[inline]
eq(&self, other: &BStr) -> bool628         fn eq(&self, other: &BStr) -> bool {
629             self.as_bytes() == other.as_bytes()
630         }
631     }
632 
633     impl_partial_eq!(BStr, [u8]);
634     impl_partial_eq!(BStr, &'a [u8]);
635     impl_partial_eq!(BStr, str);
636     impl_partial_eq!(BStr, &'a str);
637 
638     #[cfg(feature = "std")]
639     impl_partial_eq!(BStr, Vec<u8>);
640     #[cfg(feature = "std")]
641     impl_partial_eq!(&'a BStr, Vec<u8>);
642     #[cfg(feature = "std")]
643     impl_partial_eq!(BStr, String);
644     #[cfg(feature = "std")]
645     impl_partial_eq!(&'a BStr, String);
646     #[cfg(feature = "std")]
647     impl_partial_eq_cow!(&'a BStr, Cow<'a, BStr>);
648     #[cfg(feature = "std")]
649     impl_partial_eq_cow!(&'a BStr, Cow<'a, str>);
650     #[cfg(feature = "std")]
651     impl_partial_eq_cow!(&'a BStr, Cow<'a, [u8]>);
652 
653     impl PartialOrd for BStr {
654         #[inline]
partial_cmp(&self, other: &BStr) -> Option<Ordering>655         fn partial_cmp(&self, other: &BStr) -> Option<Ordering> {
656             PartialOrd::partial_cmp(self.as_bytes(), other.as_bytes())
657         }
658     }
659 
660     impl Ord for BStr {
661         #[inline]
cmp(&self, other: &BStr) -> Ordering662         fn cmp(&self, other: &BStr) -> Ordering {
663             self.partial_cmp(other).unwrap()
664         }
665     }
666 
667     impl_partial_ord!(BStr, [u8]);
668     impl_partial_ord!(BStr, &'a [u8]);
669     impl_partial_ord!(BStr, str);
670     impl_partial_ord!(BStr, &'a str);
671 
672     #[cfg(feature = "std")]
673     impl_partial_ord!(BStr, Vec<u8>);
674     #[cfg(feature = "std")]
675     impl_partial_ord!(&'a BStr, Vec<u8>);
676     #[cfg(feature = "std")]
677     impl_partial_ord!(BStr, String);
678     #[cfg(feature = "std")]
679     impl_partial_ord!(&'a BStr, String);
680 }
681 
682 #[cfg(feature = "serde1-nostd")]
683 mod bstr_serde {
684     use core::fmt;
685 
686     use serde::{
687         de::Error, de::Visitor, Deserialize, Deserializer, Serialize,
688         Serializer,
689     };
690 
691     use crate::bstr::BStr;
692 
693     impl Serialize for BStr {
694         #[inline]
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,695         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
696         where
697             S: Serializer,
698         {
699             serializer.serialize_bytes(self.as_bytes())
700         }
701     }
702 
703     impl<'a, 'de: 'a> Deserialize<'de> for &'a BStr {
704         #[inline]
deserialize<D>(deserializer: D) -> Result<&'a BStr, D::Error> where D: Deserializer<'de>,705         fn deserialize<D>(deserializer: D) -> Result<&'a BStr, D::Error>
706         where
707             D: Deserializer<'de>,
708         {
709             struct BStrVisitor;
710 
711             impl<'de> Visitor<'de> for BStrVisitor {
712                 type Value = &'de BStr;
713 
714                 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
715                     f.write_str("a borrowed byte string")
716                 }
717 
718                 #[inline]
719                 fn visit_borrowed_bytes<E: Error>(
720                     self,
721                     value: &'de [u8],
722                 ) -> Result<&'de BStr, E> {
723                     Ok(BStr::new(value))
724                 }
725 
726                 #[inline]
727                 fn visit_borrowed_str<E: Error>(
728                     self,
729                     value: &'de str,
730                 ) -> Result<&'de BStr, E> {
731                     Ok(BStr::new(value))
732                 }
733             }
734 
735             deserializer.deserialize_bytes(BStrVisitor)
736         }
737     }
738 }
739 
740 #[cfg(feature = "serde1")]
741 mod bstring_serde {
742     use std::cmp;
743     use std::fmt;
744 
745     use serde::{
746         de::Error, de::SeqAccess, de::Visitor, Deserialize, Deserializer,
747         Serialize, Serializer,
748     };
749 
750     use crate::bstring::BString;
751 
752     impl Serialize for BString {
753         #[inline]
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,754         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
755         where
756             S: Serializer,
757         {
758             serializer.serialize_bytes(self.as_bytes())
759         }
760     }
761 
762     impl<'de> Deserialize<'de> for BString {
763         #[inline]
deserialize<D>(deserializer: D) -> Result<BString, D::Error> where D: Deserializer<'de>,764         fn deserialize<D>(deserializer: D) -> Result<BString, D::Error>
765         where
766             D: Deserializer<'de>,
767         {
768             struct BStringVisitor;
769 
770             impl<'de> Visitor<'de> for BStringVisitor {
771                 type Value = BString;
772 
773                 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
774                     f.write_str("a byte string")
775                 }
776 
777                 #[inline]
778                 fn visit_seq<V: SeqAccess<'de>>(
779                     self,
780                     mut visitor: V,
781                 ) -> Result<BString, V::Error> {
782                     let len = cmp::min(visitor.size_hint().unwrap_or(0), 256);
783                     let mut bytes = Vec::with_capacity(len);
784                     while let Some(v) = visitor.next_element()? {
785                         bytes.push(v);
786                     }
787                     Ok(BString::from(bytes))
788                 }
789 
790                 #[inline]
791                 fn visit_bytes<E: Error>(
792                     self,
793                     value: &[u8],
794                 ) -> Result<BString, E> {
795                     Ok(BString::from(value))
796                 }
797 
798                 #[inline]
799                 fn visit_byte_buf<E: Error>(
800                     self,
801                     value: Vec<u8>,
802                 ) -> Result<BString, E> {
803                     Ok(BString::from(value))
804                 }
805 
806                 #[inline]
807                 fn visit_str<E: Error>(
808                     self,
809                     value: &str,
810                 ) -> Result<BString, E> {
811                     Ok(BString::from(value))
812                 }
813 
814                 #[inline]
815                 fn visit_string<E: Error>(
816                     self,
817                     value: String,
818                 ) -> Result<BString, E> {
819                     Ok(BString::from(value))
820                 }
821             }
822 
823             deserializer.deserialize_byte_buf(BStringVisitor)
824         }
825     }
826 }
827 
828 #[cfg(test)]
829 mod display {
830     use crate::bstring::BString;
831     use crate::ByteSlice;
832 
833     #[test]
clean()834     fn clean() {
835         assert_eq!(&format!("{}", &b"abc".as_bstr()), "abc");
836         assert_eq!(&format!("{}", &b"\xf0\x28\x8c\xbc".as_bstr()), "�(��");
837     }
838 
839     #[test]
width_bigger_than_bstr()840     fn width_bigger_than_bstr() {
841         assert_eq!(&format!("{:<7}!", &b"abc".as_bstr()), "abc    !");
842         assert_eq!(&format!("{:>7}!", &b"abc".as_bstr()), "    abc!");
843         assert_eq!(&format!("{:^7}!", &b"abc".as_bstr()), "  abc  !");
844         assert_eq!(&format!("{:^6}!", &b"abc".as_bstr()), " abc  !");
845         assert_eq!(&format!("{:-<7}!", &b"abc".as_bstr()), "abc----!");
846         assert_eq!(&format!("{:->7}!", &b"abc".as_bstr()), "----abc!");
847         assert_eq!(&format!("{:-^7}!", &b"abc".as_bstr()), "--abc--!");
848         assert_eq!(&format!("{:-^6}!", &b"abc".as_bstr()), "-abc--!");
849 
850         assert_eq!(
851             &format!("{:<7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
852             "�(��   !"
853         );
854         assert_eq!(
855             &format!("{:>7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
856             "   �(��!"
857         );
858         assert_eq!(
859             &format!("{:^7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
860             " �(��  !"
861         );
862         assert_eq!(
863             &format!("{:^6}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
864             " �(�� !"
865         );
866 
867         assert_eq!(
868             &format!("{:-<7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
869             "�(��---!"
870         );
871         assert_eq!(
872             &format!("{:->7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
873             "---�(��!"
874         );
875         assert_eq!(
876             &format!("{:-^7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
877             "-�(��--!"
878         );
879         assert_eq!(
880             &format!("{:-^6}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
881             "-�(��-!"
882         );
883     }
884 
885     #[test]
width_lesser_than_bstr()886     fn width_lesser_than_bstr() {
887         assert_eq!(&format!("{:<2}!", &b"abc".as_bstr()), "abc!");
888         assert_eq!(&format!("{:>2}!", &b"abc".as_bstr()), "abc!");
889         assert_eq!(&format!("{:^2}!", &b"abc".as_bstr()), "abc!");
890         assert_eq!(&format!("{:-<2}!", &b"abc".as_bstr()), "abc!");
891         assert_eq!(&format!("{:->2}!", &b"abc".as_bstr()), "abc!");
892         assert_eq!(&format!("{:-^2}!", &b"abc".as_bstr()), "abc!");
893 
894         assert_eq!(
895             &format!("{:<3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
896             "�(��!"
897         );
898         assert_eq!(
899             &format!("{:>3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
900             "�(��!"
901         );
902         assert_eq!(
903             &format!("{:^3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
904             "�(��!"
905         );
906         assert_eq!(
907             &format!("{:^2}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
908             "�(��!"
909         );
910 
911         assert_eq!(
912             &format!("{:-<3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
913             "�(��!"
914         );
915         assert_eq!(
916             &format!("{:->3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
917             "�(��!"
918         );
919         assert_eq!(
920             &format!("{:-^3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
921             "�(��!"
922         );
923         assert_eq!(
924             &format!("{:-^2}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
925             "�(��!"
926         );
927     }
928 
929     quickcheck::quickcheck! {
930         fn total_length(bstr: BString) -> bool {
931             let size = bstr.chars().count();
932             format!("{:<1$}", bstr.as_bstr(), size).chars().count() >= size
933         }
934     }
935 }
936 
937 #[cfg(test)]
938 mod bstring_arbitrary {
939     use crate::bstring::BString;
940 
941     use quickcheck::{Arbitrary, Gen};
942 
943     impl Arbitrary for BString {
arbitrary(g: &mut Gen) -> BString944         fn arbitrary(g: &mut Gen) -> BString {
945             BString::from(Vec::<u8>::arbitrary(g))
946         }
947 
shrink(&self) -> Box<dyn Iterator<Item = BString>>948         fn shrink(&self) -> Box<dyn Iterator<Item = BString>> {
949             Box::new(self.bytes.shrink().map(BString::from))
950         }
951     }
952 }
953 
954 #[test]
test_debug()955 fn test_debug() {
956     use crate::{ByteSlice, B};
957 
958     assert_eq!(
959         r#""\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp""#,
960         format!("{:?}", b"\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp".as_bstr()),
961     );
962 
963     // Tests that if the underlying bytes contain the UTF-8 encoding of the
964     // replacement codepoint, then we emit the codepoint just like other
965     // non-printable Unicode characters.
966     assert_eq!(
967         b"\"\\xFF\xEF\xBF\xBD\\xFF\"".as_bstr(),
968         // Before fixing #72, the output here would be:
969         //   \\xFF\\xEF\\xBF\\xBD\\xFF
970         B(&format!("{:?}", b"\xFF\xEF\xBF\xBD\xFF".as_bstr())).as_bstr(),
971     );
972 }
973 
974 // See: https://github.com/BurntSushi/bstr/issues/82
975 #[test]
test_cows_regression()976 fn test_cows_regression() {
977     use crate::ByteSlice;
978     use std::borrow::Cow;
979 
980     let c1 = Cow::from(b"hello bstr".as_bstr());
981     let c2 = b"goodbye bstr".as_bstr();
982     assert_ne!(c1, c2);
983 
984     let c3 = Cow::from("hello str");
985     let c4 = "goodbye str";
986     assert_ne!(c3, c4);
987 }
988