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 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 21 macro_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 41 mod 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] fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result48 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] fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result55 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] fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result62 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] fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result72 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] deref(&self) -> &[u8]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] index(&self, idx: usize) -> &u899 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] index(&self, _: ops::RangeFull) -> &Bytes108 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] index(&self, r: ops::Range<usize>) -> &Bytes117 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] index(&self, r: ops::RangeInclusive<usize>) -> &Bytes126 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] index(&self, r: ops::RangeFrom<usize>) -> &Bytes135 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] index(&self, r: ops::RangeTo<usize>) -> &Bytes144 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] index(&self, r: ops::RangeToInclusive<usize>) -> &Bytes153 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] as_ref(&self) -> &[u8]160 fn as_ref(&self) -> &[u8] { 161 self.as_bytes() 162 } 163 } 164 165 impl AsRef<Bytes> for [u8] { 166 #[inline] as_ref(&self) -> &Bytes167 fn as_ref(&self) -> &Bytes { 168 Bytes::new(self) 169 } 170 } 171 172 impl AsRef<Bytes> for str { 173 #[inline] as_ref(&self) -> &Bytes174 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] to_owned(&self) -> Self::Owned184 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] borrow(&self) -> &Bytes192 fn borrow(&self) -> &Bytes { 193 Bytes::from_bytes(self.as_slice()) 194 } 195 } 196 197 impl<'a> Default for &'a Bytes { default() -> &'a Bytes198 fn default() -> &'a Bytes { 199 Bytes::new(b"") 200 } 201 } 202 203 impl<'a> From<&'a [u8]> for &'a Bytes { 204 #[inline] from(s: &'a [u8]) -> &'a Bytes205 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] from(s: &'a Bytes) -> &'a [u8]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] from(s: &'a str) -> &'a Bytes219 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] eq(&self, other: &Bytes) -> bool228 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] partial_cmp(&self, other: &Bytes) -> Option<Ordering>240 fn partial_cmp(&self, other: &Bytes) -> Option<Ordering> { 241 Some(self.cmp(other)) 242 } 243 } 244 245 impl Ord for Bytes { 246 #[inline] cmp(&self, other: &Bytes) -> Ordering247 fn cmp(&self, other: &Bytes) -> Ordering { 248 Ord::cmp(self.as_bytes(), other.as_bytes()) 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] clean()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] test_debug()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] test_pretty_debug()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] test_sliced()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 303 mod 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] fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result311 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] fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result318 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] deref(&self) -> &[u8]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] index(&self, idx: usize) -> &u8346 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] index(&self, _: ops::RangeFull) -> &BStr355 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] index(&self, r: ops::Range<usize>) -> &BStr364 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] index(&self, r: ops::RangeInclusive<usize>) -> &BStr373 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] index(&self, r: ops::RangeFrom<usize>) -> &BStr382 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] index(&self, r: ops::RangeTo<usize>) -> &BStr391 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] index(&self, r: ops::RangeToInclusive<usize>) -> &BStr400 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] as_ref(&self) -> &[u8]407 fn as_ref(&self) -> &[u8] { 408 self.as_bytes() 409 } 410 } 411 412 impl AsRef<BStr> for [u8] { 413 #[inline] as_ref(&self) -> &BStr414 fn as_ref(&self) -> &BStr { 415 BStr::new(self) 416 } 417 } 418 419 impl AsRef<BStr> for str { 420 #[inline] as_ref(&self) -> &BStr421 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] to_owned(&self) -> Self::Owned431 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] borrow(&self) -> &BStr439 fn borrow(&self) -> &BStr { 440 BStr::from_bytes(self.as_slice()) 441 } 442 } 443 444 impl<'a> Default for &'a BStr { default() -> &'a BStr445 fn default() -> &'a BStr { 446 BStr::new(b"") 447 } 448 } 449 450 impl<'a> From<&'a [u8]> for &'a BStr { 451 #[inline] from(s: &'a [u8]) -> &'a BStr452 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] from(s: &'a BStr) -> &'a [u8]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] from(s: &'a str) -> &'a BStr466 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] eq(&self, other: &BStr) -> bool475 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] partial_cmp(&self, other: &BStr) -> Option<Ordering>487 fn partial_cmp(&self, other: &BStr) -> Option<Ordering> { 488 Some(self.cmp(other)) 489 } 490 } 491 492 impl Ord for BStr { 493 #[inline] cmp(&self, other: &BStr) -> Ordering494 fn cmp(&self, other: &BStr) -> Ordering { 495 Ord::cmp(self.as_bytes(), other.as_bytes()) 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] clean()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] test_debug()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] test_pretty_debug()533 fn test_pretty_debug() { 534 assert_eq!(&format!("{:#?}", BStr::new(b"abc")), "abc"); 535 } 536 } 537 } 538