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