1use core::{
8 borrow::Borrow,
9 cmp::Ordering,
10 fmt,
11 hash::{Hash, Hasher},
12 ops::{Bound, Deref, RangeBounds},
13};
14
15use bytes::{Bytes, BytesMut};
16
17#[derive(Clone)]
45pub enum CowBytes<'a> {
46 Borrowed(&'a [u8]),
48 Owned(Bytes),
50 OwnedMut(BytesMut),
52}
53
54impl<'a> CowBytes<'a> {
55 #[inline]
67 pub const fn borrowed(bytes: &'a [u8]) -> Self {
68 Self::Borrowed(bytes)
69 }
70
71 #[inline]
84 pub const fn owned(bytes: Bytes) -> Self {
85 Self::Owned(bytes)
86 }
87
88 #[inline]
101 pub const fn owned_mut(bytes: BytesMut) -> Self {
102 Self::OwnedMut(bytes)
103 }
104
105 #[inline]
117 pub const fn new() -> Self {
118 Self::Owned(Bytes::new())
119 }
120
121 #[inline]
135 pub const fn from_static(bytes: &'static [u8]) -> Self {
136 Self::Owned(Bytes::from_static(bytes))
137 }
138
139 #[inline]
150 pub fn copy_from_slice(data: &[u8]) -> Self {
151 Self::Owned(Bytes::copy_from_slice(data))
152 }
153
154 #[inline]
165 pub fn len(&self) -> usize {
166 match self {
167 Self::Borrowed(bytes) => bytes.len(),
168 Self::Owned(bytes) => bytes.len(),
169 Self::OwnedMut(bytes) => bytes.len(),
170 }
171 }
172
173 #[inline]
184 pub fn is_empty(&self) -> bool {
185 self.len() == 0
186 }
187
188 #[inline]
202 pub const fn is_borrowed(&self) -> bool {
203 matches!(self, Self::Borrowed(_))
204 }
205
206 #[inline]
220 pub const fn is_owned(&self) -> bool {
221 matches!(self, Self::Owned(_))
222 }
223
224 #[inline]
239 pub const fn is_owned_mut(&self) -> bool {
240 matches!(self, Self::OwnedMut(_))
241 }
242
243 #[inline]
257 pub fn to_owned(&self) -> CowBytes<'static> {
258 match self {
259 Self::Borrowed(bytes) => CowBytes::Owned(Bytes::copy_from_slice(bytes)),
260 Self::Owned(bytes) => CowBytes::Owned(bytes.clone()),
261 Self::OwnedMut(bytes) => CowBytes::OwnedMut(bytes.clone()),
262 }
263 }
264
265 #[inline]
281 pub fn into_owned(self) -> CowBytes<'static> {
282 match self {
283 Self::Borrowed(bytes) => CowBytes::Owned(Bytes::copy_from_slice(bytes)),
284 Self::Owned(bytes) => CowBytes::Owned(bytes),
285 Self::OwnedMut(bytes) => CowBytes::OwnedMut(bytes),
286 }
287 }
288
289 #[inline]
306 pub fn borrow(&self) -> CowBytes<'_> {
307 CowBytes::Borrowed(self.as_slice())
308 }
309
310 #[inline]
322 pub fn into_bytes(self) -> Bytes {
323 match self {
324 Self::Borrowed(bytes) => Bytes::copy_from_slice(bytes),
325 Self::Owned(bytes) => bytes,
326 Self::OwnedMut(bytes) => bytes.freeze(),
327 }
328 }
329
330 #[inline]
342 pub fn into_bytes_mut(self) -> BytesMut {
343 match self {
344 Self::Borrowed(bytes) => BytesMut::from(bytes),
345 Self::Owned(bytes) => BytesMut::from(bytes),
346 Self::OwnedMut(bytes) => bytes,
347 }
348 }
349
350 #[inline]
373 pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
374 match self {
375 Self::Borrowed(bytes) => {
376 let start = match range.start_bound() {
377 Bound::Included(&n) => n,
378 Bound::Excluded(&n) => n + 1,
379 Bound::Unbounded => 0,
380 };
381 let end = match range.end_bound() {
382 Bound::Included(&n) => n + 1,
383 Bound::Excluded(&n) => n,
384 Bound::Unbounded => bytes.len(),
385 };
386 Self::Borrowed(&bytes[start..end])
387 },
388 Self::Owned(bytes) => Self::Owned(bytes.slice(range)),
389 Self::OwnedMut(bytes) => {
390 Self::Owned(bytes.clone().freeze().slice(range))
393 },
394 }
395 }
396
397 #[inline]
409 pub fn clear(&mut self) {
410 match self {
411 Self::Borrowed(_) => *self = Self::Owned(Bytes::new()),
412 Self::Owned(bytes) => {
413 *bytes = Bytes::new();
414 },
415 Self::OwnedMut(bytes) => bytes.clear(),
416 }
417 }
418
419 #[inline]
433 pub fn truncate(&mut self, len: usize) {
434 if len >= self.len() {
435 return;
436 }
437 match self {
438 Self::Borrowed(bytes) => *bytes = &bytes[..len],
439 Self::Owned(bytes) => bytes.truncate(len),
440 Self::OwnedMut(bytes) => bytes.truncate(len),
441 }
442 }
443
444 #[inline]
464 pub fn split_off(&mut self, at: usize) -> Self {
465 match self {
466 Self::Borrowed(bytes) => {
467 let (left, right) = bytes.split_at(at);
468 *bytes = left;
469 Self::Borrowed(right)
470 },
471 Self::Owned(bytes) => Self::Owned(bytes.split_off(at)),
472 Self::OwnedMut(bytes) => Self::OwnedMut(bytes.split_off(at)),
473 }
474 }
475
476 #[inline]
496 pub fn split_to(&mut self, at: usize) -> Self {
497 match self {
498 Self::Borrowed(bytes) => {
499 let (left, right) = bytes.split_at(at);
500 *bytes = right;
501 Self::Borrowed(left)
502 },
503 Self::Owned(bytes) => Self::Owned(bytes.split_to(at)),
504 Self::OwnedMut(bytes) => Self::OwnedMut(bytes.split_to(at)),
505 }
506 }
507
508 #[inline]
525 pub fn is_unique(&self) -> bool {
526 match self {
527 Self::Borrowed(_) => false,
528 Self::Owned(bytes) => bytes.is_unique(),
529 Self::OwnedMut(_) => true,
530 }
531 }
532
533 #[inline]
544 pub fn as_slice(&self) -> &[u8] {
545 match self {
546 Self::Borrowed(bytes) => bytes,
547 Self::Owned(bytes) => bytes,
548 Self::OwnedMut(bytes) => bytes,
549 }
550 }
551}
552
553impl Default for CowBytes<'_> {
554 #[inline]
555 fn default() -> Self {
556 Self::new()
557 }
558}
559
560impl Deref for CowBytes<'_> {
561 type Target = [u8];
562
563 #[inline]
564 fn deref(&self) -> &[u8] {
565 self.as_slice()
566 }
567}
568
569impl AsRef<[u8]> for CowBytes<'_> {
570 #[inline]
571 fn as_ref(&self) -> &[u8] {
572 self.as_slice()
573 }
574}
575
576impl Borrow<[u8]> for CowBytes<'_> {
577 #[inline]
578 fn borrow(&self) -> &[u8] {
579 self.as_slice()
580 }
581}
582
583impl<'a> From<&'a [u8]> for CowBytes<'a> {
584 #[inline]
585 fn from(slice: &'a [u8]) -> Self {
586 Self::Borrowed(slice)
587 }
588}
589
590impl<'a, const N: usize> From<&'a [u8; N]> for CowBytes<'a> {
591 #[inline]
592 fn from(slice: &'a [u8; N]) -> Self {
593 Self::Borrowed(slice)
594 }
595}
596
597impl<const N: usize> From<[u8; N]> for CowBytes<'_> {
598 #[inline]
599 fn from(slice: [u8; N]) -> Self {
600 Self::Owned(Bytes::from_owner(slice))
601 }
602}
603
604impl<'a> From<&'a str> for CowBytes<'a> {
605 #[inline]
606 fn from(s: &'a str) -> Self {
607 Self::Borrowed(s.as_bytes())
608 }
609}
610
611impl From<Bytes> for CowBytes<'_> {
612 #[inline]
613 fn from(bytes: Bytes) -> Self {
614 Self::Owned(bytes)
615 }
616}
617
618impl From<BytesMut> for CowBytes<'_> {
619 #[inline]
620 fn from(bytes: BytesMut) -> Self {
621 Self::OwnedMut(bytes)
622 }
623}
624
625impl From<Vec<u8>> for CowBytes<'_> {
626 #[inline]
627 fn from(vec: Vec<u8>) -> Self {
628 Self::Owned(Bytes::from(vec))
629 }
630}
631
632impl From<Box<[u8]>> for CowBytes<'_> {
633 #[inline]
634 fn from(vec: Box<[u8]>) -> Self {
635 Self::Owned(Bytes::from_owner(vec))
636 }
637}
638
639impl From<String> for CowBytes<'_> {
640 #[inline]
641 fn from(s: String) -> Self {
642 Self::Owned(Bytes::from(s))
643 }
644}
645
646impl<'a> From<CowBytes<'a>> for Bytes {
647 #[inline]
648 fn from(cow: CowBytes<'a>) -> Self {
649 cow.into_bytes()
650 }
651}
652
653impl<'a> From<CowBytes<'a>> for BytesMut {
654 #[inline]
655 fn from(cow: CowBytes<'a>) -> Self {
656 match cow {
657 CowBytes::Borrowed(bytes) => Self::from(bytes),
658 CowBytes::Owned(bytes) => Self::from(bytes),
659 CowBytes::OwnedMut(bytes) => bytes,
660 }
661 }
662}
663
664impl serde::Serialize for CowBytes<'_> {
669 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
670 serializer.serialize_bytes(self.as_ref())
671 }
672}
673
674struct CowBytesVisitor<'a>(core::marker::PhantomData<&'a [u8]>);
675
676impl<'a, 'de: 'a> serde::de::Visitor<'de> for CowBytesVisitor<'a> {
677 type Value = CowBytes<'a>;
678
679 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
680 formatter.write_str("bytes, a byte sequence, or a UTF-8 string")
681 }
682
683 fn visit_borrowed_bytes<E>(self, value: &'de [u8]) -> Result<Self::Value, E>
684 where
685 E: serde::de::Error,
686 {
687 Ok(CowBytes::Borrowed(value))
688 }
689
690 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
691 where
692 E: serde::de::Error,
693 {
694 Ok(CowBytes::copy_from_slice(value))
695 }
696
697 fn visit_byte_buf<E>(self, value: Vec<u8>) -> Result<Self::Value, E>
698 where
699 E: serde::de::Error,
700 {
701 Ok(CowBytes::Owned(Bytes::from(value)))
702 }
703
704 fn visit_seq<A>(self, mut sequence: A) -> Result<Self::Value, A::Error>
705 where
706 A: serde::de::SeqAccess<'de>,
707 {
708 let mut bytes = Vec::with_capacity(sequence.size_hint().unwrap_or(0));
709 while let Some(byte) = sequence.next_element()? {
710 bytes.push(byte);
711 }
712 Ok(CowBytes::Owned(Bytes::from(bytes)))
713 }
714
715 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
716 where
717 E: serde::de::Error,
718 {
719 Ok(CowBytes::Borrowed(value.as_bytes()))
720 }
721
722 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
723 where
724 E: serde::de::Error,
725 {
726 Ok(CowBytes::copy_from_slice(value.as_bytes()))
727 }
728
729 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
730 where
731 E: serde::de::Error,
732 {
733 Ok(CowBytes::Owned(Bytes::from(value.into_bytes())))
734 }
735}
736
737impl<'a, 'de: 'a> serde::Deserialize<'de> for CowBytes<'a> {
742 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
743 deserializer.deserialize_bytes(CowBytesVisitor(core::marker::PhantomData))
744 }
745}
746
747impl fmt::Debug for CowBytes<'_> {
748 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
749 fmt::Debug::fmt(self.as_slice(), f)
750 }
751}
752
753impl fmt::Display for CowBytes<'_> {
754 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
755 write!(f, "{:?}", self.as_slice())
756 }
757}
758
759impl PartialEq for CowBytes<'_> {
760 #[inline]
761 fn eq(&self, other: &Self) -> bool {
762 self.as_slice() == other.as_slice()
763 }
764}
765
766impl Eq for CowBytes<'_> {}
767
768impl PartialOrd for CowBytes<'_> {
769 #[inline]
770 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
771 Some(self.cmp(other))
772 }
773}
774
775impl Ord for CowBytes<'_> {
776 #[inline]
777 fn cmp(&self, other: &Self) -> Ordering {
778 self.as_slice().cmp(other.as_slice())
779 }
780}
781
782impl Hash for CowBytes<'_> {
783 #[inline]
784 fn hash<H: Hasher>(&self, state: &mut H) {
785 self.as_slice().hash(state);
786 }
787}
788
789impl<'a> PartialEq<&'a [u8]> for CowBytes<'_> {
790 #[inline]
791 fn eq(&self, other: &&'a [u8]) -> bool {
792 self.as_slice() == *other
793 }
794}
795
796impl<'a> PartialEq<CowBytes<'a>> for &'a [u8] {
797 #[inline]
798 fn eq(&self, other: &CowBytes<'a>) -> bool {
799 *self == other.as_slice()
800 }
801}
802
803impl PartialEq<[u8]> for CowBytes<'_> {
804 #[inline]
805 fn eq(&self, other: &[u8]) -> bool {
806 self.as_slice() == other
807 }
808}
809
810impl PartialEq<CowBytes<'_>> for [u8] {
811 #[inline]
812 fn eq(&self, other: &CowBytes<'_>) -> bool {
813 self == other.as_slice()
814 }
815}
816
817impl<'a> PartialEq<&'a str> for CowBytes<'_> {
818 #[inline]
819 fn eq(&self, other: &&'a str) -> bool {
820 self.as_slice() == other.as_bytes()
821 }
822}
823
824impl<'a> PartialEq<CowBytes<'a>> for &'a str {
825 #[inline]
826 fn eq(&self, other: &CowBytes<'a>) -> bool {
827 self.as_bytes() == other.as_slice()
828 }
829}
830
831impl PartialEq<str> for CowBytes<'_> {
832 #[inline]
833 fn eq(&self, other: &str) -> bool {
834 self.as_slice() == other.as_bytes()
835 }
836}
837
838impl PartialEq<CowBytes<'_>> for str {
839 #[inline]
840 fn eq(&self, other: &CowBytes<'_>) -> bool {
841 self.as_bytes() == other.as_slice()
842 }
843}
844
845impl PartialEq<Bytes> for CowBytes<'_> {
846 #[inline]
847 fn eq(&self, other: &Bytes) -> bool {
848 self.as_slice() == &**other
849 }
850}
851
852impl PartialEq<CowBytes<'_>> for Bytes {
853 #[inline]
854 fn eq(&self, other: &CowBytes<'_>) -> bool {
855 &**self == other.as_slice()
856 }
857}
858
859impl PartialEq<String> for CowBytes<'_> {
860 #[inline]
861 fn eq(&self, other: &String) -> bool {
862 self.as_slice() == other.as_bytes()
863 }
864}
865
866impl PartialEq<CowBytes<'_>> for String {
867 #[inline]
868 fn eq(&self, other: &CowBytes<'_>) -> bool {
869 self.as_bytes() == other.as_slice()
870 }
871}
872
873impl<const N: usize> PartialEq<&[u8; N]> for CowBytes<'_> {
874 #[inline]
875 fn eq(&self, other: &&[u8; N]) -> bool {
876 self.as_slice() == &other[..]
877 }
878}
879
880impl<const N: usize> PartialEq<CowBytes<'_>> for &[u8; N] {
881 #[inline]
882 fn eq(&self, other: &CowBytes<'_>) -> bool {
883 &self[..] == other.as_slice()
884 }
885}
886
887impl<const N: usize> PartialEq<[u8; N]> for CowBytes<'_> {
888 #[inline]
889 fn eq(&self, other: &[u8; N]) -> bool {
890 self.as_slice() == &other[..]
891 }
892}
893
894impl<const N: usize> PartialEq<CowBytes<'_>> for [u8; N] {
895 #[inline]
896 fn eq(&self, other: &CowBytes<'_>) -> bool {
897 &self[..] == other.as_slice()
898 }
899}
900
901#[cfg(test)]
902mod tests {
903 use core::hash::{Hash, Hasher};
904 use std::collections::hash_map::DefaultHasher;
905
906 use proptest::prelude::*;
907
908 use super::*;
909
910 #[test]
915 fn test_borrowed_construction() {
916 let data = b"hello";
917 let cow = CowBytes::borrowed(data);
918 assert!(cow.is_borrowed());
919 assert!(!cow.is_owned());
920 assert!(!cow.is_owned_mut());
921 assert_eq!(&*cow, data);
922 }
923
924 #[test]
925 fn test_owned_construction() {
926 let bytes = Bytes::from(vec![1, 2, 3]);
927 let cow = CowBytes::owned(bytes);
928 assert!(!cow.is_borrowed());
929 assert!(cow.is_owned());
930 assert!(!cow.is_owned_mut());
931 assert_eq!(&*cow, &[1, 2, 3]);
932 }
933
934 #[test]
935 fn test_owned_mut_construction() {
936 let bytes = BytesMut::from(&[1, 2, 3][..]);
937 let cow = CowBytes::owned_mut(bytes);
938 assert!(!cow.is_borrowed());
939 assert!(!cow.is_owned());
940 assert!(cow.is_owned_mut());
941 assert_eq!(&*cow, &[1, 2, 3]);
942 }
943
944 #[test]
945 fn test_new_is_empty_owned() {
946 let cow = CowBytes::new();
947 assert!(cow.is_empty());
948 assert!(cow.is_owned());
949 assert_eq!(cow.len(), 0);
950 }
951
952 #[test]
953 fn test_from_static() {
954 let cow = CowBytes::from_static(b"static data");
955 assert!(cow.is_owned());
956 assert_eq!(&*cow, b"static data");
957 }
958
959 #[test]
960 fn test_copy_from_slice() {
961 let cow = CowBytes::copy_from_slice(b"copied");
962 assert!(cow.is_owned());
963 assert_eq!(&*cow, b"copied");
964 }
965
966 #[test]
971 fn test_split_off_borrowed() {
972 let data = b"hello world";
973 let mut cow = CowBytes::borrowed(data);
974 let rest = cow.split_off(6);
975
976 assert!(cow.is_borrowed());
977 assert!(rest.is_borrowed());
978 assert_eq!(&*cow, b"hello ");
979 assert_eq!(&*rest, b"world");
980 }
981
982 #[test]
983 fn test_split_off_borrowed_at_zero() {
984 let data = b"hello";
985 let mut cow = CowBytes::borrowed(data);
986 let rest = cow.split_off(0);
987
988 assert_eq!(&*cow, b"");
989 assert_eq!(&*rest, b"hello");
990 }
991
992 #[test]
993 fn test_split_off_borrowed_at_end() {
994 let data = b"hello";
995 let mut cow = CowBytes::borrowed(data);
996 let rest = cow.split_off(5);
997
998 assert_eq!(&*cow, b"hello");
999 assert_eq!(&*rest, b"");
1000 }
1001
1002 #[test]
1003 fn test_split_to_borrowed() {
1004 let data = b"hello world";
1005 let mut cow = CowBytes::borrowed(data);
1006 let prefix = cow.split_to(6);
1007
1008 assert!(cow.is_borrowed());
1009 assert!(prefix.is_borrowed());
1010 assert_eq!(&*prefix, b"hello ");
1011 assert_eq!(&*cow, b"world");
1012 }
1013
1014 #[test]
1015 fn test_split_to_borrowed_at_zero() {
1016 let data = b"hello";
1017 let mut cow = CowBytes::borrowed(data);
1018 let prefix = cow.split_to(0);
1019
1020 assert_eq!(&*prefix, b"");
1021 assert_eq!(&*cow, b"hello");
1022 }
1023
1024 #[test]
1025 fn test_split_to_borrowed_at_end() {
1026 let data = b"hello";
1027 let mut cow = CowBytes::borrowed(data);
1028 let prefix = cow.split_to(5);
1029
1030 assert_eq!(&*prefix, b"hello");
1031 assert_eq!(&*cow, b"");
1032 }
1033
1034 #[test]
1035 #[should_panic(expected = "mid > len")]
1036 fn test_split_off_borrowed_out_of_bounds() {
1037 let data = b"hello";
1038 let mut cow = CowBytes::borrowed(data);
1039 cow.split_off(10);
1040 }
1041
1042 #[test]
1043 #[should_panic(expected = "mid > len")]
1044 fn test_split_to_borrowed_out_of_bounds() {
1045 let data = b"hello";
1046 let mut cow = CowBytes::borrowed(data);
1047 cow.split_to(10);
1048 }
1049
1050 #[test]
1055 fn test_split_off_owned() {
1056 let mut cow = CowBytes::owned(Bytes::from(b"hello world".to_vec()));
1057 let rest = cow.split_off(6);
1058
1059 assert!(cow.is_owned());
1060 assert!(rest.is_owned());
1061 assert_eq!(&*cow, b"hello ");
1062 assert_eq!(&*rest, b"world");
1063 }
1064
1065 #[test]
1066 fn test_split_to_owned() {
1067 let mut cow = CowBytes::owned(Bytes::from(b"hello world".to_vec()));
1068 let prefix = cow.split_to(6);
1069
1070 assert!(cow.is_owned());
1071 assert!(prefix.is_owned());
1072 assert_eq!(&*prefix, b"hello ");
1073 assert_eq!(&*cow, b"world");
1074 }
1075
1076 #[test]
1081 fn test_split_off_owned_mut() {
1082 let mut cow = CowBytes::owned_mut(BytesMut::from(&b"hello world"[..]));
1083 let rest = cow.split_off(6);
1084
1085 assert!(cow.is_owned_mut());
1086 assert!(rest.is_owned_mut());
1087 assert_eq!(&*cow, b"hello ");
1088 assert_eq!(&*rest, b"world");
1089 }
1090
1091 #[test]
1092 fn test_split_to_owned_mut() {
1093 let mut cow = CowBytes::owned_mut(BytesMut::from(&b"hello world"[..]));
1094 let prefix = cow.split_to(6);
1095
1096 assert!(cow.is_owned_mut());
1097 assert!(prefix.is_owned_mut());
1098 assert_eq!(&*prefix, b"hello ");
1099 assert_eq!(&*cow, b"world");
1100 }
1101
1102 #[test]
1107 fn test_slice_borrowed() {
1108 let cow = CowBytes::borrowed(b"hello world");
1109 let slice = cow.slice(0..5);
1110
1111 assert!(slice.is_borrowed());
1112 assert_eq!(&*slice, b"hello");
1113 }
1114
1115 #[test]
1116 fn test_slice_owned() {
1117 let cow = CowBytes::owned(Bytes::from(b"hello world".to_vec()));
1118 let slice = cow.slice(0..5);
1119
1120 assert!(slice.is_owned());
1121 assert_eq!(&*slice, b"hello");
1122 }
1123
1124 #[test]
1125 fn test_slice_owned_mut() {
1126 let cow = CowBytes::owned_mut(BytesMut::from(&b"hello world"[..]));
1127 let slice = cow.slice(0..5);
1128
1129 assert!(slice.is_owned());
1131 assert_eq!(&*slice, b"hello");
1132 }
1133
1134 #[test]
1135 fn test_slice_full_range() {
1136 let cow = CowBytes::borrowed(b"hello");
1137 let slice = cow.slice(..);
1138 assert_eq!(&*slice, b"hello");
1139 }
1140
1141 #[test]
1142 fn test_slice_from_range() {
1143 let cow = CowBytes::borrowed(b"hello");
1144 let slice = cow.slice(2..);
1145 assert_eq!(&*slice, b"llo");
1146 }
1147
1148 #[test]
1149 fn test_slice_to_range() {
1150 let cow = CowBytes::borrowed(b"hello");
1151 let slice = cow.slice(..3);
1152 assert_eq!(&*slice, b"hel");
1153 }
1154
1155 #[test]
1156 fn test_slice_inclusive_range() {
1157 let cow = CowBytes::borrowed(b"hello");
1158 let slice = cow.slice(1..=3);
1159 assert_eq!(&*slice, b"ell");
1160 }
1161
1162 #[test]
1163 #[should_panic(expected = "range end index 10 out of range for slice of length 5")]
1164 fn test_slice_out_of_bounds() {
1165 let cow = CowBytes::borrowed(b"hello");
1166 cow.slice(0..10);
1167 }
1168
1169 #[test]
1174 fn test_truncate_borrowed() {
1175 let mut cow = CowBytes::borrowed(b"hello world");
1176 cow.truncate(5);
1177 assert!(cow.is_borrowed());
1178 assert_eq!(&*cow, b"hello");
1179 }
1180
1181 #[test]
1182 fn test_truncate_owned() {
1183 let mut cow = CowBytes::owned(Bytes::from(b"hello world".to_vec()));
1184 cow.truncate(5);
1185 assert!(cow.is_owned());
1186 assert_eq!(&*cow, b"hello");
1187 }
1188
1189 #[test]
1190 fn test_truncate_owned_mut() {
1191 let mut cow = CowBytes::owned_mut(BytesMut::from(&b"hello world"[..]));
1192 cow.truncate(5);
1193 assert!(cow.is_owned_mut());
1194 assert_eq!(&*cow, b"hello");
1195 }
1196
1197 #[test]
1198 fn test_truncate_no_op_if_len_larger() {
1199 let mut cow = CowBytes::borrowed(b"hello");
1200 cow.truncate(10);
1201 assert_eq!(&*cow, b"hello");
1202 }
1203
1204 #[test]
1205 fn test_clear_borrowed() {
1206 let mut cow = CowBytes::borrowed(b"hello");
1207 cow.clear();
1208 assert!(cow.is_owned());
1209 assert!(cow.is_empty());
1210 }
1211
1212 #[test]
1213 fn test_clear_owned() {
1214 let mut cow = CowBytes::owned(Bytes::from(b"hello".to_vec()));
1215 cow.clear();
1216 assert!(cow.is_owned());
1217 assert!(cow.is_empty());
1218 }
1219
1220 #[test]
1221 fn test_clear_owned_mut() {
1222 let mut cow = CowBytes::owned_mut(BytesMut::from(&b"hello"[..]));
1223 cow.clear();
1224 assert!(cow.is_owned_mut());
1225 assert!(cow.is_empty());
1226 }
1227
1228 #[test]
1233 fn test_to_owned_borrowed() {
1234 let cow = CowBytes::borrowed(b"hello");
1235 let owned = cow.to_owned();
1236 assert!(owned.is_owned());
1237 assert_eq!(&*owned, b"hello");
1238 }
1239
1240 #[test]
1241 fn test_to_owned_owned() {
1242 let cow = CowBytes::owned(Bytes::from(b"hello".to_vec()));
1243 let owned = cow.to_owned();
1244 assert!(owned.is_owned());
1245 assert_eq!(&*owned, b"hello");
1246 }
1247
1248 #[test]
1249 fn test_into_owned_borrowed() {
1250 let cow = CowBytes::borrowed(b"hello");
1251 let owned = cow.into_owned();
1252 assert!(owned.is_owned());
1253 assert_eq!(&*owned, b"hello");
1254 }
1255
1256 #[test]
1257 fn test_into_owned_zero_cost_when_owned() {
1258 let bytes = Bytes::from(vec![1, 2, 3]);
1259 let ptr = bytes.as_ptr();
1260
1261 let cow = CowBytes::owned(bytes);
1262 let owned = cow.into_owned();
1263
1264 assert_eq!(owned.as_ptr(), ptr);
1265 assert!(owned.is_owned());
1266 }
1267
1268 #[test]
1269 fn test_borrow() {
1270 let cow = CowBytes::owned(Bytes::from(b"hello".to_vec()));
1271 let borrowed = cow.borrow();
1272 assert!(borrowed.is_borrowed());
1273 assert_eq!(&*borrowed, b"hello");
1274 }
1275
1276 #[test]
1277 fn test_into_bytes_borrowed() {
1278 let cow = CowBytes::borrowed(b"hello");
1279 let bytes = cow.into_bytes();
1280 assert_eq!(&bytes[..], b"hello");
1281 }
1282
1283 #[test]
1284 fn test_into_bytes_owned() {
1285 let cow = CowBytes::owned(Bytes::from(b"hello".to_vec()));
1286 let bytes = cow.into_bytes();
1287 assert_eq!(&bytes[..], b"hello");
1288 }
1289
1290 #[test]
1291 fn test_into_bytes_mut_borrowed() {
1292 let cow = CowBytes::borrowed(b"hello");
1293 let bytes = cow.into_bytes_mut();
1294 assert_eq!(&bytes[..], b"hello");
1295 }
1296
1297 #[test]
1298 fn test_into_bytes_mut_owned() {
1299 let cow = CowBytes::owned(Bytes::from(b"hello".to_vec()));
1300 let bytes = cow.into_bytes_mut();
1301 assert_eq!(&bytes[..], b"hello");
1302 }
1303
1304 #[test]
1305 fn test_into_bytes_mut_owned_mut() {
1306 let cow = CowBytes::owned_mut(BytesMut::from(&b"hello"[..]));
1307 let bytes = cow.into_bytes_mut();
1308 assert_eq!(&bytes[..], b"hello");
1309 }
1310
1311 #[test]
1316 fn test_from_slice() {
1317 let data: &[u8] = b"hello";
1318 let cow: CowBytes = data.into();
1319 assert!(cow.is_borrowed());
1320 assert_eq!(&*cow, b"hello");
1321 }
1322
1323 #[test]
1324 fn test_from_array_ref() {
1325 let data: &[u8; 5] = b"hello";
1326 let cow: CowBytes = data.into();
1327 assert!(cow.is_borrowed());
1328 assert_eq!(&*cow, b"hello");
1329 }
1330
1331 #[test]
1332 fn test_from_array() {
1333 let data: [u8; 5] = *b"hello";
1334 let cow: CowBytes = data.into();
1335 assert!(cow.is_owned());
1336 assert_eq!(&*cow, b"hello");
1337 }
1338
1339 #[test]
1340 fn test_from_str_ref() {
1341 let s: &str = "hello";
1342 let cow: CowBytes = s.into();
1343 assert!(cow.is_borrowed());
1344 assert_eq!(&*cow, b"hello");
1345 }
1346
1347 #[test]
1348 fn test_from_bytes() {
1349 let bytes = Bytes::from(b"hello".to_vec());
1350 let cow: CowBytes = bytes.into();
1351 assert!(cow.is_owned());
1352 assert_eq!(&*cow, b"hello");
1353 }
1354
1355 #[test]
1356 fn test_from_bytes_mut() {
1357 let bytes = BytesMut::from(&b"hello"[..]);
1358 let cow: CowBytes = bytes.into();
1359 assert!(cow.is_owned_mut());
1360 assert_eq!(&*cow, b"hello");
1361 }
1362
1363 #[test]
1364 fn test_from_vec() {
1365 let vec = vec![1, 2, 3];
1366 let cow: CowBytes = vec.into();
1367 assert!(cow.is_owned());
1368 assert_eq!(&*cow, &[1, 2, 3]);
1369 }
1370
1371 #[test]
1372 fn test_from_box_slice() {
1373 let boxed: Box<[u8]> = vec![1, 2, 3].into_boxed_slice();
1374 let cow: CowBytes = boxed.into();
1375 assert!(cow.is_owned());
1376 assert_eq!(&*cow, &[1, 2, 3]);
1377 }
1378
1379 #[test]
1380 fn test_from_string() {
1381 let s = String::from("hello");
1382 let cow: CowBytes = s.into();
1383 assert!(cow.is_owned());
1384 assert_eq!(&*cow, b"hello");
1385 }
1386
1387 #[test]
1388 fn test_into_bytes_from_cow() {
1389 let cow = CowBytes::borrowed(b"hello");
1390 let bytes: Bytes = cow.into();
1391 assert_eq!(&bytes[..], b"hello");
1392 }
1393
1394 #[test]
1395 fn test_into_bytes_mut_from_cow() {
1396 let cow = CowBytes::borrowed(b"hello");
1397 let bytes: BytesMut = cow.into();
1398 assert_eq!(&bytes[..], b"hello");
1399 }
1400
1401 #[test]
1406 fn test_is_unique_borrowed() {
1407 let cow = CowBytes::borrowed(b"hello");
1408 assert!(!cow.is_unique());
1409 }
1410
1411 #[test]
1412 fn test_is_unique_owned_unique() {
1413 let cow = CowBytes::owned(Bytes::from(b"hello".to_vec()));
1414 assert!(cow.is_unique());
1415 }
1416
1417 #[test]
1418 fn test_is_unique_owned_shared() {
1419 let bytes = Bytes::from(b"hello".to_vec());
1420 let cow1 = CowBytes::owned(bytes.clone());
1421 let _cow2 = CowBytes::owned(bytes);
1422 assert!(!cow1.is_unique());
1423 }
1424
1425 #[test]
1426 fn test_is_unique_owned_mut() {
1427 let cow = CowBytes::owned_mut(BytesMut::from(&b"hello"[..]));
1428 assert!(cow.is_unique());
1429 }
1430
1431 #[test]
1436 fn test_eq_cow_cow() {
1437 let cow1 = CowBytes::borrowed(b"hello");
1438 let cow2 = CowBytes::owned(Bytes::from(b"hello".to_vec()));
1439 let cow3 = CowBytes::owned_mut(BytesMut::from(&b"hello"[..]));
1440
1441 assert_eq!(cow1, cow2);
1442 assert_eq!(cow1, cow3);
1443 assert_eq!(cow2, cow3);
1444 }
1445
1446 #[test]
1447 fn test_eq_cow_slice() {
1448 let cow = CowBytes::borrowed(b"hello");
1449 assert_eq!(cow, b"hello"[..]);
1450 assert_eq!(b"hello"[..], cow);
1451 }
1452
1453 #[test]
1454 fn test_eq_cow_slice_ref() {
1455 let cow = CowBytes::borrowed(b"hello");
1456 assert_eq!(cow, &b"hello"[..]);
1457 assert_eq!(&b"hello"[..], cow);
1458 }
1459
1460 #[test]
1461 fn test_eq_cow_str() {
1462 let cow = CowBytes::borrowed(b"hello");
1463 assert_eq!(cow, "hello");
1464 assert_eq!("hello", cow);
1465 }
1466
1467 #[test]
1468 fn test_eq_cow_str_ref() {
1469 let cow = CowBytes::borrowed(b"hello");
1470 let s: &str = "hello";
1471 assert_eq!(cow, s);
1472 assert_eq!(s, cow);
1473 }
1474
1475 #[test]
1476 fn test_eq_cow_bytes() {
1477 let cow = CowBytes::borrowed(b"hello");
1478 let bytes = Bytes::from(b"hello".to_vec());
1479 assert_eq!(cow, bytes);
1480 assert_eq!(bytes, cow);
1481 }
1482
1483 #[test]
1484 fn test_eq_cow_string() {
1485 let cow = CowBytes::borrowed(b"hello");
1486 let s = String::from("hello");
1487 assert_eq!(cow, s);
1488 assert_eq!(s, cow);
1489 }
1490
1491 #[test]
1492 fn test_eq_cow_array() {
1493 let cow = CowBytes::borrowed(b"hello");
1494 assert_eq!(cow, b"hello");
1495 assert_eq!(b"hello", cow);
1496 }
1497
1498 #[test]
1499 fn test_eq_cow_array_ref() {
1500 let cow = CowBytes::borrowed(b"hello");
1501 let arr: &[u8; 5] = b"hello";
1502 assert_eq!(cow, arr);
1503 assert_eq!(arr, cow);
1504 }
1505
1506 #[test]
1511 fn test_ord_cow() {
1512 let a = CowBytes::borrowed(b"apple");
1513 let b = CowBytes::owned(Bytes::from(b"banana".to_vec()));
1514 let c = CowBytes::owned_mut(BytesMut::from(&b"cherry"[..]));
1515
1516 assert!(a < b);
1517 assert!(b < c);
1518 assert!(a < c);
1519 }
1520
1521 #[test]
1522 fn test_partial_ord_reflexive() {
1523 let cow = CowBytes::borrowed(b"hello");
1524 assert_eq!(cow.partial_cmp(&cow), Some(core::cmp::Ordering::Equal));
1525 }
1526
1527 #[test]
1532 fn test_hash_consistency() {
1533 let cow1 = CowBytes::borrowed(b"hello");
1534 let cow2 = CowBytes::owned(Bytes::from(b"hello".to_vec()));
1535 let cow3 = CowBytes::owned_mut(BytesMut::from(&b"hello"[..]));
1536
1537 let hash1 = hash(&cow1);
1538 let hash2 = hash(&cow2);
1539 let hash3 = hash(&cow3);
1540
1541 assert_eq!(hash1, hash2);
1542 assert_eq!(hash1, hash3);
1543 }
1544
1545 #[test]
1546 fn test_hash_different_values() {
1547 let cow1 = CowBytes::borrowed(b"hello");
1548 let cow2 = CowBytes::borrowed(b"world");
1549
1550 let hash1 = hash(&cow1);
1551 let hash2 = hash(&cow2);
1552
1553 assert_ne!(hash1, hash2);
1554 }
1555
1556 fn hash<T: Hash>(val: &T) -> u64 {
1557 let mut hasher = DefaultHasher::new();
1558 val.hash(&mut hasher);
1559 hasher.finish()
1560 }
1561
1562 #[test]
1567 fn test_debug_format() {
1568 let cow = CowBytes::borrowed(b"hello");
1569 let debug = format!("{cow:?}");
1570 assert!(debug.contains("104"));
1571 }
1572
1573 #[test]
1574 fn test_display_format() {
1575 let cow = CowBytes::borrowed(b"hello");
1576 let display = format!("{cow}");
1577 assert!(display.contains("104"));
1578 }
1579
1580 #[test]
1585 fn test_serde_json_roundtrip() {
1586 let original = CowBytes::owned(Bytes::from(vec![1, 2, 3, 4, 5]));
1587 let json = serde_json::to_string(&original).unwrap();
1588 assert_eq!(json, "[1,2,3,4,5]");
1589
1590 let deserialized: CowBytes = serde_json::from_str(&json).unwrap();
1591 assert_eq!(original, deserialized);
1592 assert_eq!(&*deserialized, &[1, 2, 3, 4, 5]);
1593 }
1594
1595 #[test]
1596 fn test_serde_json_borrowed() {
1597 let cow = CowBytes::borrowed(b"hello");
1598 let json = serde_json::to_string(&cow).unwrap();
1599 let decoded: CowBytes = serde_json::from_str(&json).unwrap();
1600 assert_eq!(decoded, b"hello"[..]);
1601 }
1602
1603 #[test]
1604 fn test_serde_json_empty() {
1605 let cow = CowBytes::new();
1606 let json = serde_json::to_string(&cow).unwrap();
1607 assert_eq!(json, "[]");
1608
1609 let decoded: CowBytes = serde_json::from_str(&json).unwrap();
1610 assert!(decoded.is_empty());
1611 }
1612
1613 #[test]
1614 fn test_serde_borrowed_bytes_zero_copy() {
1615 use serde::de::value::{BorrowedBytesDeserializer, Error};
1616
1617 let original = b"borrowed";
1618 let deserializer = BorrowedBytesDeserializer::<Error>::new(original);
1619 let decoded = <CowBytes<'_> as serde::Deserialize>::deserialize(deserializer).unwrap();
1620 let CowBytes::Borrowed(bytes) = decoded else {
1621 panic!("borrowed bytes should stay borrowed");
1622 };
1623 assert_eq!(bytes, original);
1624 assert!(core::ptr::eq(bytes.as_ptr(), original.as_ptr()));
1625 }
1626
1627 proptest! {
1632 #[test]
1633 fn proptest_borrowed_roundtrip(data in prop::collection::vec(any::<u8>(), 0..1000)) {
1634 let cow = CowBytes::borrowed(&data);
1635 prop_assert_eq!(&*cow, data.as_slice());
1636 }
1637
1638 #[test]
1639 fn proptest_owned_roundtrip(data in prop::collection::vec(any::<u8>(), 0..1000)) {
1640 let cow = CowBytes::owned(Bytes::from(data.clone()));
1641 prop_assert_eq!(&*cow, data.as_slice());
1642 }
1643
1644 #[test]
1645 fn proptest_split_off_preserves_data(
1646 data in prop::collection::vec(any::<u8>(), 1..1000),
1647 at in 0usize..1000
1648 ) {
1649 let at = at % data.len();
1650 let mut cow = CowBytes::borrowed(&data);
1651 let rest = cow.split_off(at);
1652
1653 prop_assert_eq!(&*cow, &data[..at]);
1654 prop_assert_eq!(&*rest, &data[at..]);
1655 }
1656
1657 #[test]
1658 fn proptest_split_to_preserves_data(
1659 data in prop::collection::vec(any::<u8>(), 1..1000),
1660 at in 0usize..1000
1661 ) {
1662 let at = at % data.len();
1663 let mut cow = CowBytes::borrowed(&data);
1664 let prefix = cow.split_to(at);
1665
1666 prop_assert_eq!(&*prefix, &data[..at]);
1667 prop_assert_eq!(&*cow, &data[at..]);
1668 }
1669
1670 #[test]
1671 fn proptest_truncate_preserves_prefix(
1672 data in prop::collection::vec(any::<u8>(), 1..1000),
1673 len in 0usize..1000
1674 ) {
1675 let len = len % data.len();
1676 let mut cow = CowBytes::borrowed(&data);
1677 cow.truncate(len);
1678 prop_assert_eq!(&*cow, &data[..len]);
1679 }
1680
1681 #[test]
1682 fn proptest_hash_eq_consistency(data in prop::collection::vec(any::<u8>(), 0..100)) {
1683 let cow1 = CowBytes::borrowed(&data);
1684 let cow2 = CowBytes::owned(Bytes::from(data.clone()));
1685
1686 if cow1 == cow2 {
1687 prop_assert_eq!(hash(&cow1), hash(&cow2));
1688 }
1689 }
1690
1691 #[test]
1692 fn proptest_ord_consistency(
1693 data1 in prop::collection::vec(any::<u8>(), 0..100),
1694 data2 in prop::collection::vec(any::<u8>(), 0..100)
1695 ) {
1696 let cow1 = CowBytes::borrowed(&data1);
1697 let cow2 = CowBytes::borrowed(&data2);
1698
1699 let cmp1 = cow1.cmp(&cow2);
1700 let cmp2 = data1.cmp(&data2);
1701 prop_assert_eq!(cmp1, cmp2);
1702 }
1703 }
1704}