1macro_rules! impl_partial_eq {
2 ($lhs:ty, $rhs:ty) => {
3 impl<'a, 'b> PartialEq<$rhs> for $lhs {
4 #[inline]
5 fn eq(&self, other: &$rhs) -> bool {
6 let l = self.as_ref();
7 let r: &Self = other.as_ref();
8 PartialEq::eq(l, r)
9 }
10 }
11
12 impl<'a, 'b> PartialEq<$lhs> for $rhs {
13 #[inline]
14 fn eq(&self, other: &$lhs) -> bool {
15 PartialEq::eq(other, self)
16 }
17 }
18 };
19}
20
21macro_rules! impl_partial_ord {
22 ($lhs:ty, $rhs:ty) => {
23 impl<'a, 'b> PartialOrd<$rhs> for $lhs {
24 #[inline]
25 fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
26 let l = self.as_ref();
27 let r: &Self = other.as_ref();
28 PartialOrd::partial_cmp(l, r)
29 }
30 }
31
32 impl<'a, 'b> PartialOrd<$lhs> for $rhs {
33 #[inline]
34 fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
35 PartialOrd::partial_cmp(other, self)
36 }
37 }
38 };
39}
40
41mod bytes {
42 use crate::lib::std::{cmp::Ordering, fmt, ops};
43
44 use crate::stream::Bytes;
45
46 impl fmt::Display for Bytes {
47 #[inline]
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 <Self as fmt::UpperHex>::fmt(self, f)
50 }
51 }
52
53 impl fmt::Debug for Bytes {
54 #[inline]
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 <Self as fmt::UpperHex>::fmt(self, f)
57 }
58 }
59
60 impl fmt::LowerHex for Bytes {
61 #[inline]
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 for byte in self.as_bytes() {
64 write!(f, "{:0>2x}", byte)?;
65 }
66 Ok(())
67 }
68 }
69
70 impl fmt::UpperHex for Bytes {
71 #[inline]
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 for (i, byte) in self.as_bytes().iter().enumerate() {
74 if 0 < i {
75 let absolute = (self.as_bytes().as_ptr() as usize) + i;
76 if f.alternate() && absolute != 0 && absolute % 4 == 0 {
77 write!(f, "_")?;
78 }
79 }
80 write!(f, "{:0>2X}", byte)?;
81 }
82 Ok(())
83 }
84 }
85
86 impl ops::Deref for Bytes {
87 type Target = [u8];
88
89 #[inline]
90 fn deref(&self) -> &[u8] {
91 self.as_bytes()
92 }
93 }
94
95 impl ops::Index<usize> for Bytes {
96 type Output = u8;
97
98 #[inline]
99 fn index(&self, idx: usize) -> &u8 {
100 &self.as_bytes()[idx]
101 }
102 }
103
104 impl ops::Index<ops::RangeFull> for Bytes {
105 type Output = Bytes;
106
107 #[inline]
108 fn index(&self, _: ops::RangeFull) -> &Bytes {
109 self
110 }
111 }
112
113 impl ops::Index<ops::Range<usize>> for Bytes {
114 type Output = Bytes;
115
116 #[inline]
117 fn index(&self, r: ops::Range<usize>) -> &Bytes {
118 Bytes::new(&self.as_bytes()[r.start..r.end])
119 }
120 }
121
122 impl ops::Index<ops::RangeInclusive<usize>> for Bytes {
123 type Output = Bytes;
124
125 #[inline]
126 fn index(&self, r: ops::RangeInclusive<usize>) -> &Bytes {
127 Bytes::new(&self.as_bytes()[*r.start()..=*r.end()])
128 }
129 }
130
131 impl ops::Index<ops::RangeFrom<usize>> for Bytes {
132 type Output = Bytes;
133
134 #[inline]
135 fn index(&self, r: ops::RangeFrom<usize>) -> &Bytes {
136 Bytes::new(&self.as_bytes()[r.start..])
137 }
138 }
139
140 impl ops::Index<ops::RangeTo<usize>> for Bytes {
141 type Output = Bytes;
142
143 #[inline]
144 fn index(&self, r: ops::RangeTo<usize>) -> &Bytes {
145 Bytes::new(&self.as_bytes()[..r.end])
146 }
147 }
148
149 impl ops::Index<ops::RangeToInclusive<usize>> for Bytes {
150 type Output = Bytes;
151
152 #[inline]
153 fn index(&self, r: ops::RangeToInclusive<usize>) -> &Bytes {
154 Bytes::new(&self.as_bytes()[..=r.end])
155 }
156 }
157
158 impl AsRef<[u8]> for Bytes {
159 #[inline]
160 fn as_ref(&self) -> &[u8] {
161 self.as_bytes()
162 }
163 }
164
165 impl AsRef<Bytes> for [u8] {
166 #[inline]
167 fn as_ref(&self) -> &Bytes {
168 Bytes::new(self)
169 }
170 }
171
172 impl AsRef<Bytes> for str {
173 #[inline]
174 fn as_ref(&self) -> &Bytes {
175 Bytes::new(self)
176 }
177 }
178
179 #[cfg(feature = "alloc")]
180 impl crate::lib::std::borrow::ToOwned for Bytes {
181 type Owned = crate::lib::std::vec::Vec<u8>;
182
183 #[inline]
184 fn to_owned(&self) -> Self::Owned {
185 crate::lib::std::vec::Vec::from(self.as_bytes())
186 }
187 }
188
189 #[cfg(feature = "alloc")]
190 impl crate::lib::std::borrow::Borrow<Bytes> for crate::lib::std::vec::Vec<u8> {
191 #[inline]
192 fn borrow(&self) -> &Bytes {
193 Bytes::from_bytes(self.as_slice())
194 }
195 }
196
197 impl<'a> Default for &'a Bytes {
198 fn default() -> &'a Bytes {
199 Bytes::new(b"")
200 }
201 }
202
203 impl<'a> From<&'a [u8]> for &'a Bytes {
204 #[inline]
205 fn from(s: &'a [u8]) -> &'a Bytes {
206 Bytes::new(s)
207 }
208 }
209
210 impl<'a> From<&'a Bytes> for &'a [u8] {
211 #[inline]
212 fn from(s: &'a Bytes) -> &'a [u8] {
213 Bytes::as_bytes(s)
214 }
215 }
216
217 impl<'a> From<&'a str> for &'a Bytes {
218 #[inline]
219 fn from(s: &'a str) -> &'a Bytes {
220 Bytes::new(s.as_bytes())
221 }
222 }
223
224 impl Eq for Bytes {}
225
226 impl PartialEq<Bytes> for Bytes {
227 #[inline]
228 fn eq(&self, other: &Bytes) -> bool {
229 self.as_bytes() == other.as_bytes()
230 }
231 }
232
233 impl_partial_eq!(Bytes, [u8]);
234 impl_partial_eq!(Bytes, &'a [u8]);
235 impl_partial_eq!(Bytes, str);
236 impl_partial_eq!(Bytes, &'a str);
237
238 impl PartialOrd for Bytes {
239 #[inline]
240 fn partial_cmp(&self, other: &Bytes) -> Option<Ordering> {
241 PartialOrd::partial_cmp(self.as_bytes(), other.as_bytes())
242 }
243 }
244
245 impl Ord for Bytes {
246 #[inline]
247 fn cmp(&self, other: &Bytes) -> Ordering {
248 self.partial_cmp(other).unwrap()
249 }
250 }
251
252 impl_partial_ord!(Bytes, [u8]);
253 impl_partial_ord!(Bytes, &'a [u8]);
254 impl_partial_ord!(Bytes, str);
255 impl_partial_ord!(Bytes, &'a str);
256
257 #[cfg(all(test, feature = "std"))]
258 mod display {
259 use crate::stream::Bytes;
260
261 #[test]
262 fn clean() {
263 assert_eq!(&format!("{}", Bytes::new(b"abc")), "616263");
264 assert_eq!(&format!("{}", Bytes::new(b"\xf0\x28\x8c\xbc")), "F0288CBC");
265 }
266 }
267
268 #[cfg(all(test, feature = "std"))]
269 mod debug {
270 use crate::stream::Bytes;
271
272 #[test]
273 fn test_debug() {
274 assert_eq!(
275 "000000206674797069736F6D0000020069736F6D69736F32617663316D70",
276 format!(
277 "{:?}",
278 Bytes::new(b"\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp")
279 ),
280 );
281 }
282
283 #[test]
284 fn test_pretty_debug() {
285 // Output can change from run-to-run
286 format!(
287 "{:#?}",
288 Bytes::new(b"\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp")
289 );
290 }
291
292 #[test]
293 fn test_sliced() {
294 // Output can change from run-to-run
295 let total = Bytes::new(b"12345678901234567890");
296 format!("{:#?}", total);
297 format!("{:#?}", &total[1..]);
298 format!("{:#?}", &total[10..]);
299 }
300 }
301}
302
303mod bstr {
304 use crate::lib::std::{cmp::Ordering, fmt, ops};
305
306 use crate::stream::BStr;
307
308 #[cfg(feature = "alloc")]
309 impl fmt::Display for BStr {
310 #[inline]
311 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
312 crate::lib::std::string::String::from_utf8_lossy(self.as_bytes()).fmt(f)
313 }
314 }
315
316 impl fmt::Debug for BStr {
317 #[inline]
318 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
319 if !f.alternate() {
320 write!(f, "\"")?;
321 }
322 for byte in self.as_bytes() {
323 let c = *byte as char;
324 write!(f, "{}", c.escape_debug())?;
325 }
326 if !f.alternate() {
327 write!(f, "\"")?;
328 }
329 Ok(())
330 }
331 }
332
333 impl ops::Deref for BStr {
334 type Target = [u8];
335
336 #[inline]
337 fn deref(&self) -> &[u8] {
338 self.as_bytes()
339 }
340 }
341
342 impl ops::Index<usize> for BStr {
343 type Output = u8;
344
345 #[inline]
346 fn index(&self, idx: usize) -> &u8 {
347 &self.as_bytes()[idx]
348 }
349 }
350
351 impl ops::Index<ops::RangeFull> for BStr {
352 type Output = BStr;
353
354 #[inline]
355 fn index(&self, _: ops::RangeFull) -> &BStr {
356 self
357 }
358 }
359
360 impl ops::Index<ops::Range<usize>> for BStr {
361 type Output = BStr;
362
363 #[inline]
364 fn index(&self, r: ops::Range<usize>) -> &BStr {
365 BStr::new(&self.as_bytes()[r.start..r.end])
366 }
367 }
368
369 impl ops::Index<ops::RangeInclusive<usize>> for BStr {
370 type Output = BStr;
371
372 #[inline]
373 fn index(&self, r: ops::RangeInclusive<usize>) -> &BStr {
374 BStr::new(&self.as_bytes()[*r.start()..=*r.end()])
375 }
376 }
377
378 impl ops::Index<ops::RangeFrom<usize>> for BStr {
379 type Output = BStr;
380
381 #[inline]
382 fn index(&self, r: ops::RangeFrom<usize>) -> &BStr {
383 BStr::new(&self.as_bytes()[r.start..])
384 }
385 }
386
387 impl ops::Index<ops::RangeTo<usize>> for BStr {
388 type Output = BStr;
389
390 #[inline]
391 fn index(&self, r: ops::RangeTo<usize>) -> &BStr {
392 BStr::new(&self.as_bytes()[..r.end])
393 }
394 }
395
396 impl ops::Index<ops::RangeToInclusive<usize>> for BStr {
397 type Output = BStr;
398
399 #[inline]
400 fn index(&self, r: ops::RangeToInclusive<usize>) -> &BStr {
401 BStr::new(&self.as_bytes()[..=r.end])
402 }
403 }
404
405 impl AsRef<[u8]> for BStr {
406 #[inline]
407 fn as_ref(&self) -> &[u8] {
408 self.as_bytes()
409 }
410 }
411
412 impl AsRef<BStr> for [u8] {
413 #[inline]
414 fn as_ref(&self) -> &BStr {
415 BStr::new(self)
416 }
417 }
418
419 impl AsRef<BStr> for str {
420 #[inline]
421 fn as_ref(&self) -> &BStr {
422 BStr::new(self)
423 }
424 }
425
426 #[cfg(feature = "alloc")]
427 impl crate::lib::std::borrow::ToOwned for BStr {
428 type Owned = crate::lib::std::vec::Vec<u8>;
429
430 #[inline]
431 fn to_owned(&self) -> Self::Owned {
432 crate::lib::std::vec::Vec::from(self.as_bytes())
433 }
434 }
435
436 #[cfg(feature = "alloc")]
437 impl crate::lib::std::borrow::Borrow<BStr> for crate::lib::std::vec::Vec<u8> {
438 #[inline]
439 fn borrow(&self) -> &BStr {
440 BStr::from_bytes(self.as_slice())
441 }
442 }
443
444 impl<'a> Default for &'a BStr {
445 fn default() -> &'a BStr {
446 BStr::new(b"")
447 }
448 }
449
450 impl<'a> From<&'a [u8]> for &'a BStr {
451 #[inline]
452 fn from(s: &'a [u8]) -> &'a BStr {
453 BStr::new(s)
454 }
455 }
456
457 impl<'a> From<&'a BStr> for &'a [u8] {
458 #[inline]
459 fn from(s: &'a BStr) -> &'a [u8] {
460 BStr::as_bytes(s)
461 }
462 }
463
464 impl<'a> From<&'a str> for &'a BStr {
465 #[inline]
466 fn from(s: &'a str) -> &'a BStr {
467 BStr::new(s.as_bytes())
468 }
469 }
470
471 impl Eq for BStr {}
472
473 impl PartialEq<BStr> for BStr {
474 #[inline]
475 fn eq(&self, other: &BStr) -> bool {
476 self.as_bytes() == other.as_bytes()
477 }
478 }
479
480 impl_partial_eq!(BStr, [u8]);
481 impl_partial_eq!(BStr, &'a [u8]);
482 impl_partial_eq!(BStr, str);
483 impl_partial_eq!(BStr, &'a str);
484
485 impl PartialOrd for BStr {
486 #[inline]
487 fn partial_cmp(&self, other: &BStr) -> Option<Ordering> {
488 PartialOrd::partial_cmp(self.as_bytes(), other.as_bytes())
489 }
490 }
491
492 impl Ord for BStr {
493 #[inline]
494 fn cmp(&self, other: &BStr) -> Ordering {
495 self.partial_cmp(other).unwrap()
496 }
497 }
498
499 impl_partial_ord!(BStr, [u8]);
500 impl_partial_ord!(BStr, &'a [u8]);
501 impl_partial_ord!(BStr, str);
502 impl_partial_ord!(BStr, &'a str);
503
504 #[cfg(all(test, feature = "std"))]
505 mod display {
506 use crate::stream::BStr;
507
508 #[test]
509 fn clean() {
510 assert_eq!(&format!("{}", BStr::new(b"abc")), "abc");
511 assert_eq!(&format!("{}", BStr::new(b"\xf0\x28\x8c\xbc")), "�(��");
512 }
513 }
514
515 #[cfg(all(test, feature = "std"))]
516 mod debug {
517 use crate::stream::BStr;
518
519 #[test]
520 fn test_debug() {
521 assert_eq!(&format!("{:?}", BStr::new(b"abc")), "\"abc\"");
522
523 assert_eq!(
524 "\"\\0\\0\\0 ftypisom\\0\\0\\u{2}\\0isomiso2avc1mp\"",
525 format!(
526 "{:?}",
527 BStr::new(b"\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp")
528 ),
529 );
530 }
531
532 #[test]
533 fn test_pretty_debug() {
534 assert_eq!(&format!("{:#?}", BStr::new(b"abc")), "abc");
535 }
536 }
537}
538