• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 bstr::BStr;
71     use bstring::BString;
72     use 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 bstr::BStr;
312     use 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(f: &mut fmt::Formatter, num: usize) -> fmt::Result {
333                 let fill = f.fill();
334                 for _ in 0..num {
335                     f.write_fmt(format_args!("{}", fill))?;
336                 }
337                 Ok(())
338             }
339 
340             if let Some(align) = f.align() {
341                 let width = f.width().unwrap_or(0);
342                 let nchars = self.chars().count();
343                 let remaining_pads = width.saturating_sub(nchars);
344                 match align {
345                     fmt::Alignment::Left => {
346                         write_bstr(f, self)?;
347                         write_pads(f, remaining_pads)?;
348                     }
349                     fmt::Alignment::Right => {
350                         write_pads(f, remaining_pads)?;
351                         write_bstr(f, self)?;
352                     }
353                     fmt::Alignment::Center => {
354                         let half = remaining_pads / 2;
355                         let second_half = if remaining_pads % 2 == 0 {
356                             half
357                         } else {
358                             half + 1
359                         };
360                         write_pads(f, half)?;
361                         write_bstr(f, self)?;
362                         write_pads(f, second_half)?;
363                     }
364                 }
365                 Ok(())
366             } else {
367                 write_bstr(f, self)?;
368                 Ok(())
369             }
370         }
371     }
372 
373     impl fmt::Debug for BStr {
374         #[inline]
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result375         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
376             write!(f, "\"")?;
377             for (s, e, ch) in self.char_indices() {
378                 match ch {
379                     '\0' => write!(f, "\\0")?,
380                     '\u{FFFD}' => {
381                         let bytes = self[s..e].as_bytes();
382                         if bytes == b"\xEF\xBF\xBD" {
383                             write!(f, "{}", ch.escape_debug())?;
384                         } else {
385                             for &b in self[s..e].as_bytes() {
386                                 write!(f, r"\x{:02X}", b)?;
387                             }
388                         }
389                     }
390                     // ASCII control characters except \0, \n, \r, \t
391                     '\x01'..='\x08'
392                     | '\x0b'
393                     | '\x0c'
394                     | '\x0e'..='\x19'
395                     | '\x7f' => {
396                         write!(f, "\\x{:02x}", ch as u32)?;
397                     }
398                     '\n' | '\r' | '\t' | _ => {
399                         write!(f, "{}", ch.escape_debug())?;
400                     }
401                 }
402             }
403             write!(f, "\"")?;
404             Ok(())
405         }
406     }
407 
408     impl ops::Deref for BStr {
409         type Target = [u8];
410 
411         #[inline]
deref(&self) -> &[u8]412         fn deref(&self) -> &[u8] {
413             &self.bytes
414         }
415     }
416 
417     impl ops::DerefMut for BStr {
418         #[inline]
deref_mut(&mut self) -> &mut [u8]419         fn deref_mut(&mut self) -> &mut [u8] {
420             &mut self.bytes
421         }
422     }
423 
424     impl ops::Index<usize> for BStr {
425         type Output = u8;
426 
427         #[inline]
index(&self, idx: usize) -> &u8428         fn index(&self, idx: usize) -> &u8 {
429             &self.as_bytes()[idx]
430         }
431     }
432 
433     impl ops::Index<ops::RangeFull> for BStr {
434         type Output = BStr;
435 
436         #[inline]
index(&self, _: ops::RangeFull) -> &BStr437         fn index(&self, _: ops::RangeFull) -> &BStr {
438             self
439         }
440     }
441 
442     impl ops::Index<ops::Range<usize>> for BStr {
443         type Output = BStr;
444 
445         #[inline]
index(&self, r: ops::Range<usize>) -> &BStr446         fn index(&self, r: ops::Range<usize>) -> &BStr {
447             BStr::new(&self.as_bytes()[r.start..r.end])
448         }
449     }
450 
451     impl ops::Index<ops::RangeInclusive<usize>> for BStr {
452         type Output = BStr;
453 
454         #[inline]
index(&self, r: ops::RangeInclusive<usize>) -> &BStr455         fn index(&self, r: ops::RangeInclusive<usize>) -> &BStr {
456             BStr::new(&self.as_bytes()[*r.start()..=*r.end()])
457         }
458     }
459 
460     impl ops::Index<ops::RangeFrom<usize>> for BStr {
461         type Output = BStr;
462 
463         #[inline]
index(&self, r: ops::RangeFrom<usize>) -> &BStr464         fn index(&self, r: ops::RangeFrom<usize>) -> &BStr {
465             BStr::new(&self.as_bytes()[r.start..])
466         }
467     }
468 
469     impl ops::Index<ops::RangeTo<usize>> for BStr {
470         type Output = BStr;
471 
472         #[inline]
index(&self, r: ops::RangeTo<usize>) -> &BStr473         fn index(&self, r: ops::RangeTo<usize>) -> &BStr {
474             BStr::new(&self.as_bytes()[..r.end])
475         }
476     }
477 
478     impl ops::Index<ops::RangeToInclusive<usize>> for BStr {
479         type Output = BStr;
480 
481         #[inline]
index(&self, r: ops::RangeToInclusive<usize>) -> &BStr482         fn index(&self, r: ops::RangeToInclusive<usize>) -> &BStr {
483             BStr::new(&self.as_bytes()[..=r.end])
484         }
485     }
486 
487     impl ops::IndexMut<usize> for BStr {
488         #[inline]
index_mut(&mut self, idx: usize) -> &mut u8489         fn index_mut(&mut self, idx: usize) -> &mut u8 {
490             &mut self.bytes[idx]
491         }
492     }
493 
494     impl ops::IndexMut<ops::RangeFull> for BStr {
495         #[inline]
index_mut(&mut self, _: ops::RangeFull) -> &mut BStr496         fn index_mut(&mut self, _: ops::RangeFull) -> &mut BStr {
497             self
498         }
499     }
500 
501     impl ops::IndexMut<ops::Range<usize>> for BStr {
502         #[inline]
index_mut(&mut self, r: ops::Range<usize>) -> &mut BStr503         fn index_mut(&mut self, r: ops::Range<usize>) -> &mut BStr {
504             BStr::from_bytes_mut(&mut self.bytes[r.start..r.end])
505         }
506     }
507 
508     impl ops::IndexMut<ops::RangeInclusive<usize>> for BStr {
509         #[inline]
index_mut(&mut self, r: ops::RangeInclusive<usize>) -> &mut BStr510         fn index_mut(&mut self, r: ops::RangeInclusive<usize>) -> &mut BStr {
511             BStr::from_bytes_mut(&mut self.bytes[*r.start()..=*r.end()])
512         }
513     }
514 
515     impl ops::IndexMut<ops::RangeFrom<usize>> for BStr {
516         #[inline]
index_mut(&mut self, r: ops::RangeFrom<usize>) -> &mut BStr517         fn index_mut(&mut self, r: ops::RangeFrom<usize>) -> &mut BStr {
518             BStr::from_bytes_mut(&mut self.bytes[r.start..])
519         }
520     }
521 
522     impl ops::IndexMut<ops::RangeTo<usize>> for BStr {
523         #[inline]
index_mut(&mut self, r: ops::RangeTo<usize>) -> &mut BStr524         fn index_mut(&mut self, r: ops::RangeTo<usize>) -> &mut BStr {
525             BStr::from_bytes_mut(&mut self.bytes[..r.end])
526         }
527     }
528 
529     impl ops::IndexMut<ops::RangeToInclusive<usize>> for BStr {
530         #[inline]
index_mut(&mut self, r: ops::RangeToInclusive<usize>) -> &mut BStr531         fn index_mut(&mut self, r: ops::RangeToInclusive<usize>) -> &mut BStr {
532             BStr::from_bytes_mut(&mut self.bytes[..=r.end])
533         }
534     }
535 
536     impl AsRef<[u8]> for BStr {
537         #[inline]
as_ref(&self) -> &[u8]538         fn as_ref(&self) -> &[u8] {
539             self.as_bytes()
540         }
541     }
542 
543     impl AsRef<BStr> for [u8] {
544         #[inline]
as_ref(&self) -> &BStr545         fn as_ref(&self) -> &BStr {
546             BStr::new(self)
547         }
548     }
549 
550     impl AsRef<BStr> for str {
551         #[inline]
as_ref(&self) -> &BStr552         fn as_ref(&self) -> &BStr {
553             BStr::new(self)
554         }
555     }
556 
557     impl AsMut<[u8]> for BStr {
558         #[inline]
as_mut(&mut self) -> &mut [u8]559         fn as_mut(&mut self) -> &mut [u8] {
560             &mut self.bytes
561         }
562     }
563 
564     impl AsMut<BStr> for [u8] {
565         #[inline]
as_mut(&mut self) -> &mut BStr566         fn as_mut(&mut self) -> &mut BStr {
567             BStr::new_mut(self)
568         }
569     }
570 
571     impl<'a> Default for &'a BStr {
default() -> &'a BStr572         fn default() -> &'a BStr {
573             BStr::from_bytes(b"")
574         }
575     }
576 
577     impl<'a> Default for &'a mut BStr {
default() -> &'a mut BStr578         fn default() -> &'a mut BStr {
579             BStr::from_bytes_mut(&mut [])
580         }
581     }
582 
583     impl<'a> From<&'a [u8]> for &'a BStr {
584         #[inline]
from(s: &'a [u8]) -> &'a BStr585         fn from(s: &'a [u8]) -> &'a BStr {
586             BStr::from_bytes(s)
587         }
588     }
589 
590     impl<'a> From<&'a str> for &'a BStr {
591         #[inline]
from(s: &'a str) -> &'a BStr592         fn from(s: &'a str) -> &'a BStr {
593             BStr::from_bytes(s.as_bytes())
594         }
595     }
596 
597     #[cfg(feature = "std")]
598     impl<'a> From<&'a BStr> for Cow<'a, BStr> {
599         #[inline]
from(s: &'a BStr) -> Cow<'a, BStr>600         fn from(s: &'a BStr) -> Cow<'a, BStr> {
601             Cow::Borrowed(s)
602         }
603     }
604 
605     #[cfg(feature = "std")]
606     impl From<Box<[u8]>> for Box<BStr> {
607         #[inline]
from(s: Box<[u8]>) -> Box<BStr>608         fn from(s: Box<[u8]>) -> Box<BStr> {
609             BStr::from_boxed_bytes(s)
610         }
611     }
612 
613     #[cfg(feature = "std")]
614     impl From<Box<BStr>> for Box<[u8]> {
615         #[inline]
from(s: Box<BStr>) -> Box<[u8]>616         fn from(s: Box<BStr>) -> Box<[u8]> {
617             BStr::into_boxed_bytes(s)
618         }
619     }
620 
621     impl Eq for BStr {}
622 
623     impl PartialEq<BStr> for BStr {
624         #[inline]
eq(&self, other: &BStr) -> bool625         fn eq(&self, other: &BStr) -> bool {
626             self.as_bytes() == other.as_bytes()
627         }
628     }
629 
630     impl_partial_eq!(BStr, [u8]);
631     impl_partial_eq!(BStr, &'a [u8]);
632     impl_partial_eq!(BStr, str);
633     impl_partial_eq!(BStr, &'a str);
634 
635     #[cfg(feature = "std")]
636     impl_partial_eq!(BStr, Vec<u8>);
637     #[cfg(feature = "std")]
638     impl_partial_eq!(&'a BStr, Vec<u8>);
639     #[cfg(feature = "std")]
640     impl_partial_eq!(BStr, String);
641     #[cfg(feature = "std")]
642     impl_partial_eq!(&'a BStr, String);
643     #[cfg(feature = "std")]
644     impl_partial_eq_cow!(&'a BStr, Cow<'a, BStr>);
645     #[cfg(feature = "std")]
646     impl_partial_eq_cow!(&'a BStr, Cow<'a, str>);
647     #[cfg(feature = "std")]
648     impl_partial_eq_cow!(&'a BStr, Cow<'a, [u8]>);
649 
650     impl PartialOrd for BStr {
651         #[inline]
partial_cmp(&self, other: &BStr) -> Option<Ordering>652         fn partial_cmp(&self, other: &BStr) -> Option<Ordering> {
653             PartialOrd::partial_cmp(self.as_bytes(), other.as_bytes())
654         }
655     }
656 
657     impl Ord for BStr {
658         #[inline]
cmp(&self, other: &BStr) -> Ordering659         fn cmp(&self, other: &BStr) -> Ordering {
660             self.partial_cmp(other).unwrap()
661         }
662     }
663 
664     impl_partial_ord!(BStr, [u8]);
665     impl_partial_ord!(BStr, &'a [u8]);
666     impl_partial_ord!(BStr, str);
667     impl_partial_ord!(BStr, &'a str);
668 
669     #[cfg(feature = "std")]
670     impl_partial_ord!(BStr, Vec<u8>);
671     #[cfg(feature = "std")]
672     impl_partial_ord!(&'a BStr, Vec<u8>);
673     #[cfg(feature = "std")]
674     impl_partial_ord!(BStr, String);
675     #[cfg(feature = "std")]
676     impl_partial_ord!(&'a BStr, String);
677 }
678 
679 #[cfg(feature = "serde1-nostd")]
680 mod bstr_serde {
681     use core::fmt;
682 
683     use serde::{
684         de::Error, de::Visitor, Deserialize, Deserializer, Serialize,
685         Serializer,
686     };
687 
688     use bstr::BStr;
689 
690     impl Serialize for BStr {
691         #[inline]
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,692         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
693         where
694             S: Serializer,
695         {
696             serializer.serialize_bytes(self.as_bytes())
697         }
698     }
699 
700     impl<'a, 'de: 'a> Deserialize<'de> for &'a BStr {
701         #[inline]
deserialize<D>(deserializer: D) -> Result<&'a BStr, D::Error> where D: Deserializer<'de>,702         fn deserialize<D>(deserializer: D) -> Result<&'a BStr, D::Error>
703         where
704             D: Deserializer<'de>,
705         {
706             struct BStrVisitor;
707 
708             impl<'de> Visitor<'de> for BStrVisitor {
709                 type Value = &'de BStr;
710 
711                 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
712                     f.write_str("a borrowed byte string")
713                 }
714 
715                 #[inline]
716                 fn visit_borrowed_bytes<E: Error>(
717                     self,
718                     value: &'de [u8],
719                 ) -> Result<&'de BStr, E> {
720                     Ok(BStr::new(value))
721                 }
722 
723                 #[inline]
724                 fn visit_borrowed_str<E: Error>(
725                     self,
726                     value: &'de str,
727                 ) -> Result<&'de BStr, E> {
728                     Ok(BStr::new(value))
729                 }
730             }
731 
732             deserializer.deserialize_bytes(BStrVisitor)
733         }
734     }
735 }
736 
737 #[cfg(feature = "serde1")]
738 mod bstring_serde {
739     use std::cmp;
740     use std::fmt;
741 
742     use serde::{
743         de::Error, de::SeqAccess, de::Visitor, Deserialize, Deserializer,
744         Serialize, Serializer,
745     };
746 
747     use bstring::BString;
748 
749     impl Serialize for BString {
750         #[inline]
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,751         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
752         where
753             S: Serializer,
754         {
755             serializer.serialize_bytes(self.as_bytes())
756         }
757     }
758 
759     impl<'de> Deserialize<'de> for BString {
760         #[inline]
deserialize<D>(deserializer: D) -> Result<BString, D::Error> where D: Deserializer<'de>,761         fn deserialize<D>(deserializer: D) -> Result<BString, D::Error>
762         where
763             D: Deserializer<'de>,
764         {
765             struct BStringVisitor;
766 
767             impl<'de> Visitor<'de> for BStringVisitor {
768                 type Value = BString;
769 
770                 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
771                     f.write_str("a byte string")
772                 }
773 
774                 #[inline]
775                 fn visit_seq<V: SeqAccess<'de>>(
776                     self,
777                     mut visitor: V,
778                 ) -> Result<BString, V::Error> {
779                     let len = cmp::min(visitor.size_hint().unwrap_or(0), 256);
780                     let mut bytes = Vec::with_capacity(len);
781                     while let Some(v) = visitor.next_element()? {
782                         bytes.push(v);
783                     }
784                     Ok(BString::from(bytes))
785                 }
786 
787                 #[inline]
788                 fn visit_bytes<E: Error>(
789                     self,
790                     value: &[u8],
791                 ) -> Result<BString, E> {
792                     Ok(BString::from(value))
793                 }
794 
795                 #[inline]
796                 fn visit_byte_buf<E: Error>(
797                     self,
798                     value: Vec<u8>,
799                 ) -> Result<BString, E> {
800                     Ok(BString::from(value))
801                 }
802 
803                 #[inline]
804                 fn visit_str<E: Error>(
805                     self,
806                     value: &str,
807                 ) -> Result<BString, E> {
808                     Ok(BString::from(value))
809                 }
810 
811                 #[inline]
812                 fn visit_string<E: Error>(
813                     self,
814                     value: String,
815                 ) -> Result<BString, E> {
816                     Ok(BString::from(value))
817                 }
818             }
819 
820             deserializer.deserialize_byte_buf(BStringVisitor)
821         }
822     }
823 }
824 
825 #[cfg(test)]
826 mod display {
827     use crate::ByteSlice;
828     use bstring::BString;
829 
830     #[test]
clean()831     fn clean() {
832         assert_eq!(&format!("{}", &b"abc".as_bstr()), "abc");
833         assert_eq!(&format!("{}", &b"\xf0\x28\x8c\xbc".as_bstr()), "�(��");
834     }
835 
836     #[test]
width_bigger_than_bstr()837     fn width_bigger_than_bstr() {
838         assert_eq!(&format!("{:<7}!", &b"abc".as_bstr()), "abc    !");
839         assert_eq!(&format!("{:>7}!", &b"abc".as_bstr()), "    abc!");
840         assert_eq!(&format!("{:^7}!", &b"abc".as_bstr()), "  abc  !");
841         assert_eq!(&format!("{:^6}!", &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!("{:-^7}!", &b"abc".as_bstr()), "--abc--!");
845         assert_eq!(&format!("{:-^6}!", &b"abc".as_bstr()), "-abc--!");
846 
847         assert_eq!(
848             &format!("{:<7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
849             "�(��   !"
850         );
851         assert_eq!(
852             &format!("{:>7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
853             "   �(��!"
854         );
855         assert_eq!(
856             &format!("{:^7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
857             " �(��  !"
858         );
859         assert_eq!(
860             &format!("{:^6}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
861             " �(�� !"
862         );
863 
864         assert_eq!(
865             &format!("{:-<7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
866             "�(��---!"
867         );
868         assert_eq!(
869             &format!("{:->7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
870             "---�(��!"
871         );
872         assert_eq!(
873             &format!("{:-^7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
874             "-�(��--!"
875         );
876         assert_eq!(
877             &format!("{:-^6}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
878             "-�(��-!"
879         );
880     }
881 
882     #[test]
width_lesser_than_bstr()883     fn width_lesser_than_bstr() {
884         assert_eq!(&format!("{:<2}!", &b"abc".as_bstr()), "abc!");
885         assert_eq!(&format!("{:>2}!", &b"abc".as_bstr()), "abc!");
886         assert_eq!(&format!("{:^2}!", &b"abc".as_bstr()), "abc!");
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 
891         assert_eq!(
892             &format!("{:<3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
893             "�(��!"
894         );
895         assert_eq!(
896             &format!("{:>3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
897             "�(��!"
898         );
899         assert_eq!(
900             &format!("{:^3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
901             "�(��!"
902         );
903         assert_eq!(
904             &format!("{:^2}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
905             "�(��!"
906         );
907 
908         assert_eq!(
909             &format!("{:-<3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
910             "�(��!"
911         );
912         assert_eq!(
913             &format!("{:->3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
914             "�(��!"
915         );
916         assert_eq!(
917             &format!("{:-^3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
918             "�(��!"
919         );
920         assert_eq!(
921             &format!("{:-^2}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
922             "�(��!"
923         );
924     }
925 
926     quickcheck! {
927         fn total_length(bstr: BString) -> bool {
928             let size = bstr.chars().count();
929             format!("{:<1$}", bstr.as_bstr(), size).chars().count() >= size
930         }
931     }
932 }
933 
934 #[cfg(test)]
935 mod bstring_arbitrary {
936     use bstring::BString;
937 
938     use quickcheck::{Arbitrary, Gen};
939 
940     impl Arbitrary for BString {
arbitrary(g: &mut Gen) -> BString941         fn arbitrary(g: &mut Gen) -> BString {
942             BString::from(Vec::<u8>::arbitrary(g))
943         }
944 
shrink(&self) -> Box<dyn Iterator<Item = BString>>945         fn shrink(&self) -> Box<dyn Iterator<Item = BString>> {
946             Box::new(self.bytes.shrink().map(BString::from))
947         }
948     }
949 }
950 
951 #[test]
test_debug()952 fn test_debug() {
953     use crate::{ByteSlice, B};
954 
955     assert_eq!(
956         r#""\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp""#,
957         format!("{:?}", b"\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp".as_bstr()),
958     );
959 
960     // Tests that if the underlying bytes contain the UTF-8 encoding of the
961     // replacement codepoint, then we emit the codepoint just like other
962     // non-printable Unicode characters.
963     assert_eq!(
964         b"\"\\xFF\xEF\xBF\xBD\\xFF\"".as_bstr(),
965         // Before fixing #72, the output here would be:
966         //   \\xFF\\xEF\\xBF\\xBD\\xFF
967         B(&format!("{:?}", b"\xFF\xEF\xBF\xBD\xFF".as_bstr())).as_bstr(),
968     );
969 }
970 
971 // See: https://github.com/BurntSushi/bstr/issues/82
972 #[test]
test_cows_regression()973 fn test_cows_regression() {
974     use crate::ByteSlice;
975     use std::borrow::Cow;
976 
977     let c1 = Cow::from(b"hello bstr".as_bstr());
978     let c2 = b"goodbye bstr".as_bstr();
979     assert_ne!(c1, c2);
980 
981     let c3 = Cow::from("hello str");
982     let c4 = "goodbye str";
983     assert_ne!(c3, c4);
984 }
985