Skip to main content

omp_core/
cow_bytes.rs

1//! Clone-on-write byte slice with `Bytes` as the owned variant.
2//!
3//! Provides a `Cow`-like type where the borrowed variant is `&[u8]` and the
4//! owned variant is `Bytes`, enabling cheap clones and zero-copy slicing when
5//! owned.
6
7use 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/// Clone-on-write byte slice with `Bytes` as the owned variant.
18///
19/// Similar to `Cow<'a, [u8]>`, but uses `Bytes` for the owned variant instead
20/// of `Vec<u8>`. This provides:
21///
22/// - Cheap cloning when owned (via reference counting)
23/// - Zero-copy slicing operations
24/// - Efficient sharing of byte buffers
25///
26/// # Examples
27///
28/// ```
29/// use omp_core::CowBytes;
30///
31/// // Borrowed variant
32/// let data = b"hello world";
33/// let cow = CowBytes::borrowed(data);
34/// assert_eq!(cow.len(), 11);
35///
36/// // Owned variant from static
37/// let cow = CowBytes::from_static(b"hello");
38/// assert_eq!(&*cow, b"hello");
39///
40/// // Owned variant from Vec
41/// let cow = CowBytes::owned(vec![1, 2, 3].into());
42/// assert_eq!(&*cow, &[1, 2, 3]);
43/// ```
44#[derive(Clone)]
45pub enum CowBytes<'a> {
46	/// Borrowed byte slice.
47	Borrowed(&'a [u8]),
48	/// Owned `Bytes` buffer.
49	Owned(Bytes),
50	/// Owned `BytesMut` buffer.
51	OwnedMut(BytesMut),
52}
53
54impl<'a> CowBytes<'a> {
55	/// Creates a borrowed variant from a byte slice.
56	///
57	/// # Examples
58	///
59	/// ```
60	/// use omp_core::CowBytes;
61	///
62	/// let data = b"hello";
63	/// let cow = CowBytes::borrowed(data);
64	/// assert!(matches!(cow, CowBytes::Borrowed(_)));
65	/// ```
66	#[inline]
67	pub const fn borrowed(bytes: &'a [u8]) -> Self {
68		Self::Borrowed(bytes)
69	}
70
71	/// Creates an owned variant from `Bytes`.
72	///
73	/// # Examples
74	///
75	/// ```
76	/// use bytes::Bytes;
77	/// use omp_core::CowBytes;
78	///
79	/// let bytes = Bytes::from(vec![1, 2, 3]);
80	/// let cow = CowBytes::owned(bytes);
81	/// assert!(matches!(cow, CowBytes::Owned(_)));
82	/// ```
83	#[inline]
84	pub const fn owned(bytes: Bytes) -> Self {
85		Self::Owned(bytes)
86	}
87
88	/// Creates an owned variant from `BytesMut`.
89	///
90	/// # Examples
91	///
92	/// ```
93	/// use bytes::{Bytes, BytesMut};
94	/// use omp_core::CowBytes;
95	///
96	/// let bytes = BytesMut::from(&[1, 2, 3][..]);
97	/// let cow = CowBytes::owned_mut(bytes);
98	/// assert!(matches!(cow, CowBytes::OwnedMut(_)));
99	/// ```
100	#[inline]
101	pub const fn owned_mut(bytes: BytesMut) -> Self {
102		Self::OwnedMut(bytes)
103	}
104
105	/// Creates an empty owned variant.
106	///
107	/// # Examples
108	///
109	/// ```
110	/// use omp_core::CowBytes;
111	///
112	/// let cow = CowBytes::new();
113	/// assert!(cow.is_empty());
114	/// assert!(matches!(cow, CowBytes::Owned(_)));
115	/// ```
116	#[inline]
117	pub const fn new() -> Self {
118		Self::Owned(Bytes::new())
119	}
120
121	/// Creates an owned variant from a static slice.
122	///
123	/// This does not allocate; the returned `Bytes` will point directly to the
124	/// static slice.
125	///
126	/// # Examples
127	///
128	/// ```
129	/// use omp_core::CowBytes;
130	///
131	/// let cow = CowBytes::from_static(b"hello");
132	/// assert_eq!(&*cow, b"hello");
133	/// ```
134	#[inline]
135	pub const fn from_static(bytes: &'static [u8]) -> Self {
136		Self::Owned(Bytes::from_static(bytes))
137	}
138
139	/// Creates an owned variant by copying a slice.
140	///
141	/// # Examples
142	///
143	/// ```
144	/// use omp_core::CowBytes;
145	///
146	/// let cow = CowBytes::copy_from_slice(b"hello");
147	/// assert_eq!(&*cow, b"hello");
148	/// ```
149	#[inline]
150	pub fn copy_from_slice(data: &[u8]) -> Self {
151		Self::Owned(Bytes::copy_from_slice(data))
152	}
153
154	/// Returns the length in bytes.
155	///
156	/// # Examples
157	///
158	/// ```
159	/// use omp_core::CowBytes;
160	///
161	/// let cow = CowBytes::borrowed(b"hello");
162	/// assert_eq!(cow.len(), 5);
163	/// ```
164	#[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	/// Returns `true` if the length is 0.
174	///
175	/// # Examples
176	///
177	/// ```
178	/// use omp_core::CowBytes;
179	///
180	/// let cow = CowBytes::new();
181	/// assert!(cow.is_empty());
182	/// ```
183	#[inline]
184	pub fn is_empty(&self) -> bool {
185		self.len() == 0
186	}
187
188	/// Returns `true` if this is the borrowed variant.
189	///
190	/// # Examples
191	///
192	/// ```
193	/// use omp_core::CowBytes;
194	///
195	/// let cow = CowBytes::borrowed(b"hello");
196	/// assert!(cow.is_borrowed());
197	///
198	/// let cow = CowBytes::new();
199	/// assert!(!cow.is_borrowed());
200	/// ```
201	#[inline]
202	pub const fn is_borrowed(&self) -> bool {
203		matches!(self, Self::Borrowed(_))
204	}
205
206	/// Returns `true` if this is the `Owned` variant.
207	///
208	/// # Examples
209	///
210	/// ```
211	/// use omp_core::CowBytes;
212	///
213	/// let cow = CowBytes::new();
214	/// assert!(cow.is_owned());
215	///
216	/// let cow = CowBytes::borrowed(b"hello");
217	/// assert!(!cow.is_owned());
218	/// ```
219	#[inline]
220	pub const fn is_owned(&self) -> bool {
221		matches!(self, Self::Owned(_))
222	}
223
224	/// Returns `true` if this is the `OwnedMut` variant.
225	///
226	/// # Examples
227	///
228	/// ```
229	/// use bytes::BytesMut;
230	/// use omp_core::CowBytes;
231	///
232	/// let cow = CowBytes::owned_mut(BytesMut::from(&[1, 2, 3][..]));
233	/// assert!(cow.is_owned_mut());
234	///
235	/// let cow = CowBytes::new();
236	/// assert!(!cow.is_owned_mut());
237	/// ```
238	#[inline]
239	pub const fn is_owned_mut(&self) -> bool {
240		matches!(self, Self::OwnedMut(_))
241	}
242
243	/// Clones this into an owned variant with `'static` lifetime.
244	///
245	/// All borrowed data will be cloned into an owned `Bytes` buffer.
246	///
247	/// # Examples
248	///
249	/// ```
250	/// use omp_core::CowBytes;
251	///
252	/// let cow = CowBytes::borrowed(b"hello");
253	/// let owned = cow.to_owned();
254	/// assert!(matches!(owned, CowBytes::Owned(_)));
255	/// ```
256	#[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	/// Converts to an owned variant with `'static` lifetime, consuming self.
266	///
267	/// This method consumes the `CowBytes` instance and converts borrowed data
268	/// into owned data, resulting in `CowBytes<'static>`. When already owned,
269	/// this is a zero-cost operation.
270	///
271	/// # Examples
272	///
273	/// ```
274	/// use omp_core::CowBytes;
275	///
276	/// let cow = CowBytes::borrowed(b"hello");
277	/// let owned = cow.into_owned();
278	/// assert!(matches!(owned, CowBytes::Owned(_)));
279	/// ```
280	#[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	/// Creates a borrowed view of this `CowBytes`.
290	///
291	/// This is useful for passing by reference without allocating. If this is
292	/// already borrowed, returns a copy of the borrow. If owned, returns a
293	/// borrowed reference to the owned data.
294	///
295	/// # Examples
296	///
297	/// ```
298	/// use omp_core::CowBytes;
299	///
300	/// let owned = CowBytes::owned(vec![1, 2, 3].into());
301	/// let borrowed = owned.borrow();
302	/// assert!(borrowed.is_borrowed());
303	/// assert_eq!(&*borrowed, &[1, 2, 3]);
304	/// ```
305	#[inline]
306	pub fn borrow(&self) -> CowBytes<'_> {
307		CowBytes::Borrowed(self.as_slice())
308	}
309
310	/// Converts to a `Bytes` instance, cloning the data if borrowed.
311	///
312	/// # Examples
313	///
314	/// ```
315	/// use omp_core::CowBytes;
316	///
317	/// let cow = CowBytes::borrowed(b"hello");
318	/// let bytes = cow.into_bytes();
319	/// assert_eq!(bytes, b"hello"[..]);
320	/// ```
321	#[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	/// Converts to a `BytesMut` instance, cloning the data if borrowed.
331	///
332	/// # Examples
333	///
334	/// ```
335	/// use omp_core::CowBytes;
336	///
337	/// let cow = CowBytes::borrowed(b"hello");
338	/// let bytes = cow.into_bytes_mut();
339	/// assert_eq!(&bytes[..], b"hello");
340	/// ```
341	#[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	/// Returns a slice of self for the provided range.
351	///
352	/// If owned, this will increment the reference count for the underlying
353	/// memory and return a new owned variant set to the slice. If borrowed,
354	/// returns a new borrowed variant.
355	///
356	/// For `OwnedMut` variant, this freezes to `Bytes` and slices, returning
357	/// an `Owned` variant.
358	///
359	/// # Examples
360	///
361	/// ```
362	/// use omp_core::CowBytes;
363	///
364	/// let cow = CowBytes::from_static(b"hello world");
365	/// let slice = cow.slice(0..5);
366	/// assert_eq!(&*slice, b"hello");
367	/// ```
368	///
369	/// # Panics
370	///
371	/// Panics if the range is out of bounds.
372	#[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				// BytesMut doesn't support cheap slicing like Bytes does,
391				// so we freeze to Bytes first
392				Self::Owned(bytes.clone().freeze().slice(range))
393			},
394		}
395	}
396
397	/// Clears the contents, converting to an empty owned variant if borrowed.
398	///
399	/// # Examples
400	///
401	/// ```
402	/// use omp_core::CowBytes;
403	///
404	/// let mut cow = CowBytes::from_static(b"hello");
405	/// cow.clear();
406	/// assert!(cow.is_empty());
407	/// ```
408	#[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	/// Shortens the buffer, keeping the first `len` bytes.
420	///
421	/// If `len` is greater than the current length, this has no effect.
422	///
423	/// # Examples
424	///
425	/// ```
426	/// use omp_core::CowBytes;
427	///
428	/// let mut cow = CowBytes::from_static(b"hello world");
429	/// cow.truncate(5);
430	/// assert_eq!(&*cow, b"hello");
431	/// ```
432	#[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	/// Splits the buffer into two at the given index.
445	///
446	/// Afterwards `self` contains elements `[0, at)`, and the returned variant
447	/// contains elements `[at, len)`.
448	///
449	/// # Examples
450	///
451	/// ```
452	/// use omp_core::CowBytes;
453	///
454	/// let mut cow = CowBytes::from_static(b"hello world");
455	/// let rest = cow.split_off(6);
456	/// assert_eq!(&*cow, b"hello ");
457	/// assert_eq!(&*rest, b"world");
458	/// ```
459	///
460	/// # Panics
461	///
462	/// Panics if `at > len`.
463	#[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	/// Splits the buffer into two at the given index.
477	///
478	/// Afterwards `self` contains elements `[at, len)`, and the returned variant
479	/// contains elements `[0, at)`.
480	///
481	/// # Examples
482	///
483	/// ```
484	/// use omp_core::CowBytes;
485	///
486	/// let mut cow = CowBytes::from_static(b"hello world");
487	/// let prefix = cow.split_to(6);
488	/// assert_eq!(&*prefix, b"hello ");
489	/// assert_eq!(&*cow, b"world");
490	/// ```
491	///
492	/// # Panics
493	///
494	/// Panics if `at > len`.
495	#[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	/// Returns `true` if this is an owned variant with a unique reference to
509	/// the data.
510	///
511	/// Always returns `false` for borrowed variants.
512	///
513	/// # Examples
514	///
515	/// ```
516	/// use omp_core::CowBytes;
517	///
518	/// let cow = CowBytes::owned(vec![1, 2, 3].into());
519	/// assert!(cow.is_unique());
520	///
521	/// let cow = CowBytes::borrowed(b"hello");
522	/// assert!(!cow.is_unique());
523	/// ```
524	#[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	/// Extracts a slice containing the entire buffer.
534	///
535	/// # Examples
536	///
537	/// ```
538	/// use omp_core::CowBytes;
539	///
540	/// let cow = CowBytes::borrowed(b"hello");
541	/// assert_eq!(cow.as_slice(), b"hello");
542	/// ```
543	#[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
664/// Serializes using the serializer's native byte representation.
665///
666/// Human-readable serializers decide how bytes are represented; in
667/// `serde_json`, they are emitted as an array of numbers rather than base64.
668impl 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
737/// Deserializes borrowed bytes and strings without copying, and owns all
738/// transient byte buffers, strings, and byte sequences.
739///
740/// JSON byte arrays deserialize into the owned variant.
741impl<'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	// ============================================================================
911	// CONSTRUCTION & VARIANT CHECKS
912	// ============================================================================
913
914	#[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	// ============================================================================
967	// SPLIT OPERATIONS - BORROWED
968	// ============================================================================
969
970	#[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	// ============================================================================
1051	// SPLIT OPERATIONS - OWNED
1052	// ============================================================================
1053
1054	#[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	// ============================================================================
1077	// SPLIT OPERATIONS - OWNEDMUT
1078	// ============================================================================
1079
1080	#[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	// ============================================================================
1103	// SLICE OPERATIONS
1104	// ============================================================================
1105
1106	#[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		// OwnedMut freezes to Owned when slicing
1130		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	// ============================================================================
1170	// TRUNCATE & CLEAR
1171	// ============================================================================
1172
1173	#[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	// ============================================================================
1229	// CONVERSIONS
1230	// ============================================================================
1231
1232	#[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	// ============================================================================
1312	// FROM IMPLS
1313	// ============================================================================
1314
1315	#[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	// ============================================================================
1402	// IS_UNIQUE
1403	// ============================================================================
1404
1405	#[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	// ============================================================================
1432	// PARTIALEQ IMPLEMENTATIONS
1433	// ============================================================================
1434
1435	#[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	// ============================================================================
1507	// ORD
1508	// ============================================================================
1509
1510	#[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	// ============================================================================
1528	// HASH
1529	// ============================================================================
1530
1531	#[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	// ============================================================================
1563	// DISPLAY & DEBUG
1564	// ============================================================================
1565
1566	#[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	// ============================================================================
1581	// SERDE
1582	// ============================================================================
1583
1584	#[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	// ============================================================================
1628	// PROPTEST
1629	// ============================================================================
1630
1631	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}