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