1use alloc::borrow::{Borrow, Cow as StdCow};
5use alloc::string::String;
6use alloc::vec::Vec;
7use core::cmp::Ordering;
8use core::fmt;
9use core::hash::{Hash, Hasher};
10use core::marker::PhantomData;
11use core::mem::ManuallyDrop;
12use core::ptr::NonNull;
13
14#[cfg(target_pointer_width = "64")]
15use crate::lean::internal::Lean;
16use crate::traits::{Beef, Capacity};
17use crate::wide::internal::Wide;
18
19pub struct Cow<'a, T: Beef + ?Sized + 'a, U: Capacity> {
23 ptr: NonNull<T::PointerT>,
25
26 fat: usize,
30
31 cap: U::Field,
33
34 marker: PhantomData<&'a T>,
36}
37
38impl<T, U> Cow<'_, T, U>
39where
40 T: Beef + ?Sized,
41 U: Capacity,
42{
43 #[inline]
53 pub fn owned(val: T::Owned) -> Self {
54 let (ptr, fat, cap) = T::owned_into_parts::<U>(val);
55
56 Cow {
57 ptr,
58 fat,
59 cap,
60 marker: PhantomData,
61 }
62 }
63}
64
65impl<'a, T, U> Cow<'a, T, U>
66where
67 T: Beef + ?Sized,
68 U: Capacity,
69{
70 #[inline]
80 pub fn borrowed(val: &'a T) -> Self {
81 let (ptr, fat, cap) = T::ref_into_parts::<U>(val);
82
83 Cow {
84 ptr,
85 fat,
86 cap,
87 marker: PhantomData,
88 }
89 }
90
91 #[inline]
95 pub fn into_owned(self) -> T::Owned {
96 let cow = ManuallyDrop::new(self);
97
98 match cow.capacity() {
99 Some(capacity) => unsafe { T::owned_from_parts::<U>(cow.ptr, cow.fat, capacity) },
100 None => unsafe { &*T::ref_from_parts::<U>(cow.ptr, cow.fat) }.to_owned(),
101 }
102 }
103
104 #[inline]
108 pub fn unwrap_borrowed(self) -> &'a T {
109 if self.capacity().is_some() {
110 panic!("Can not turn owned beef::Cow into a borrowed value")
111 }
112 unsafe { &*T::ref_from_parts::<U>(self.ptr, self.fat) }
113 }
114
115 #[inline]
131 pub fn is_borrowed(&self) -> bool {
132 self.capacity().is_none()
133 }
134
135 #[inline]
151 pub fn is_owned(&self) -> bool {
152 self.capacity().is_some()
153 }
154
155 #[inline]
157 fn borrow(&self) -> &T {
158 unsafe { &*T::ref_from_parts::<U>(self.ptr, self.fat) }
159 }
160
161 #[inline]
162 fn capacity(&self) -> Option<U::NonZero> {
163 U::maybe(self.fat, self.cap)
164 }
165}
166
167impl<'a> Cow<'a, str, Wide> {
168 pub const fn const_str(val: &'a str) -> Self {
181 Cow {
182 ptr: unsafe { NonNull::new_unchecked(val.as_ptr() as *mut u8) },
185 fat: val.len(),
186 cap: None,
187 marker: PhantomData,
188 }
189 }
190}
191
192#[cfg(target_pointer_width = "64")]
193impl<'a> Cow<'a, str, Lean> {
194 pub const fn const_str(val: &'a str) -> Self {
207 Cow {
208 ptr: unsafe { NonNull::new_unchecked(val.as_ptr() as *mut u8) },
211 fat: Lean::mask_len(val.len()),
212 cap: Lean,
213 marker: PhantomData,
214 }
215 }
216}
217
218#[cfg(feature = "const_fn")]
221impl<'a, T> Cow<'a, [T], Wide>
222where
223 T: Clone,
224{
225 pub const fn const_slice(val: &'a [T]) -> Self {
238 Cow {
239 ptr: unsafe { NonNull::new_unchecked(val.as_ptr() as *mut T) },
242 fat: val.len(),
243 cap: None,
244 marker: PhantomData,
245 }
246 }
247}
248
249#[cfg(all(feature = "const_fn", target_pointer_width = "64"))]
252impl<'a, T> Cow<'a, [T], Lean>
253where
254 T: Clone,
255{
256 pub const fn const_slice(val: &'a [T]) -> Self {
269 Cow {
270 ptr: unsafe { NonNull::new_unchecked(val.as_ptr() as *mut T) },
273 fat: Lean::mask_len(val.len()),
274 cap: Lean,
275 marker: PhantomData,
276 }
277 }
278}
279
280impl<T, U> Hash for Cow<'_, T, U>
281where
282 T: Hash + Beef + ?Sized,
283 U: Capacity,
284{
285 #[inline]
286 fn hash<H: Hasher>(&self, state: &mut H) {
287 self.borrow().hash(state)
288 }
289}
290
291impl<'a, T, U> Default for Cow<'a, T, U>
292where
293 T: Beef + ?Sized,
294 U: Capacity,
295 &'a T: Default,
296{
297 #[inline]
298 fn default() -> Self {
299 Cow::borrowed(Default::default())
300 }
301}
302
303impl<T, U> Eq for Cow<'_, T, U>
304where
305 T: Eq + Beef + ?Sized,
306 U: Capacity,
307{
308}
309
310impl<A, B, U, V> PartialOrd<Cow<'_, B, V>> for Cow<'_, A, U>
311where
312 A: Beef + ?Sized + PartialOrd<B>,
313 B: Beef + ?Sized,
314 U: Capacity,
315 V: Capacity,
316{
317 #[inline]
318 fn partial_cmp(&self, other: &Cow<'_, B, V>) -> Option<Ordering> {
319 PartialOrd::partial_cmp(self.borrow(), other.borrow())
320 }
321}
322
323impl<T, U> Ord for Cow<'_, T, U>
324where
325 T: Ord + Beef + ?Sized,
326 U: Capacity,
327{
328 #[inline]
329 fn cmp(&self, other: &Self) -> Ordering {
330 Ord::cmp(self.borrow(), other.borrow())
331 }
332}
333
334impl<'a, T, U> From<&'a T> for Cow<'a, T, U>
335where
336 T: Beef + ?Sized,
337 U: Capacity,
338{
339 #[inline]
340 fn from(val: &'a T) -> Self {
341 Cow::borrowed(val)
342 }
343}
344
345impl<U> From<String> for Cow<'_, str, U>
346where
347 U: Capacity,
348{
349 #[inline]
350 fn from(s: String) -> Self {
351 Cow::owned(s)
352 }
353}
354
355impl<T, U> From<Vec<T>> for Cow<'_, [T], U>
356where
357 T: Clone,
358 U: Capacity,
359{
360 #[inline]
361 fn from(v: Vec<T>) -> Self {
362 Cow::owned(v)
363 }
364}
365
366impl<T, U> Drop for Cow<'_, T, U>
367where
368 T: Beef + ?Sized,
369 U: Capacity,
370{
371 #[inline]
372 fn drop(&mut self) {
373 if let Some(capacity) = self.capacity() {
374 unsafe { T::owned_from_parts::<U>(self.ptr, self.fat, capacity) };
375 }
376 }
377}
378
379impl<'a, T, U> Clone for Cow<'a, T, U>
380where
381 T: Beef + ?Sized,
382 U: Capacity,
383{
384 #[inline]
385 fn clone(&self) -> Self {
386 match self.capacity() {
387 Some(_) => Cow::owned(self.borrow().to_owned()),
388 None => Cow { ..*self },
389 }
390 }
391}
392
393impl<T, U> core::ops::Deref for Cow<'_, T, U>
394where
395 T: Beef + ?Sized,
396 U: Capacity,
397{
398 type Target = T;
399
400 #[inline]
401 fn deref(&self) -> &T {
402 self.borrow()
403 }
404}
405
406impl<T, U> AsRef<T> for Cow<'_, T, U>
407where
408 T: Beef + ?Sized,
409 U: Capacity,
410{
411 #[inline]
412 fn as_ref(&self) -> &T {
413 self.borrow()
414 }
415}
416
417impl<T, U> Borrow<T> for Cow<'_, T, U>
418where
419 T: Beef + ?Sized,
420 U: Capacity,
421{
422 #[inline]
423 fn borrow(&self) -> &T {
424 self.borrow()
425 }
426}
427
428impl<'a, T, U> From<StdCow<'a, T>> for Cow<'a, T, U>
429where
430 T: Beef + ?Sized,
431 U: Capacity,
432{
433 #[inline]
434 fn from(stdcow: StdCow<'a, T>) -> Self {
435 match stdcow {
436 StdCow::Borrowed(v) => Self::borrowed(v),
437 StdCow::Owned(v) => Self::owned(v),
438 }
439 }
440}
441
442impl<'a, T, U> From<Cow<'a, T, U>> for StdCow<'a, T>
443where
444 T: Beef + ?Sized,
445 U: Capacity,
446{
447 #[inline]
448 fn from(cow: Cow<'a, T, U>) -> Self {
449 let cow = ManuallyDrop::new(cow);
450
451 match cow.capacity() {
452 Some(capacity) => {
453 StdCow::Owned(unsafe { T::owned_from_parts::<U>(cow.ptr, cow.fat, capacity) })
454 }
455 None => StdCow::Borrowed(unsafe { &*T::ref_from_parts::<U>(cow.ptr, cow.fat) }),
456 }
457 }
458}
459
460impl<A, B, U, V> PartialEq<Cow<'_, B, V>> for Cow<'_, A, U>
461where
462 A: Beef + ?Sized,
463 B: Beef + ?Sized,
464 U: Capacity,
465 V: Capacity,
466 A: PartialEq<B>,
467{
468 fn eq(&self, other: &Cow<B, V>) -> bool {
469 self.borrow() == other.borrow()
470 }
471}
472
473macro_rules! impl_eq {
474 ($($(@for< $bounds:tt >)? $ptr:ty => $([$($deref:tt)+])? <$with:ty>,)*) => {$(
475 impl<U $(, $bounds)*> PartialEq<$with> for Cow<'_, $ptr, U>
476 where
477 U: Capacity,
478 $( $bounds: Clone + PartialEq, )*
479 {
480 #[inline]
481 fn eq(&self, other: &$with) -> bool {
482 self.borrow() == $($($deref)*)* other
483 }
484 }
485
486 impl<U $(, $bounds)*> PartialEq<Cow<'_, $ptr, U>> for $with
487 where
488 U: Capacity,
489 $( $bounds: Clone + PartialEq, )*
490 {
491 #[inline]
492 fn eq(&self, other: &Cow<$ptr, U>) -> bool {
493 $($($deref)*)* self == other.borrow()
494 }
495 }
496 )*};
497}
498
499impl_eq! {
500 str => <str>,
501 str => [*]<&str>,
502 str => <String>,
503 @for<T> [T] => <[T]>,
504 @for<T> [T] => [*]<&[T]>,
505 @for<T> [T] => [&**]<Vec<T>>,
506}
507
508impl<T, U> fmt::Debug for Cow<'_, T, U>
509where
510 T: Beef + fmt::Debug + ?Sized,
511 U: Capacity,
512{
513 #[inline]
514 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
515 self.borrow().fmt(f)
516 }
517}
518
519impl<T, U> fmt::Display for Cow<'_, T, U>
520where
521 T: Beef + fmt::Display + ?Sized,
522 U: Capacity,
523{
524 #[inline]
525 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
526 self.borrow().fmt(f)
527 }
528}
529
530unsafe impl<T, U> Sync for Cow<'_, T, U>
532where
533 U: Capacity,
534 T: Beef + Sync + ?Sized,
535 T::Owned: Sync,
536{
537}
538
539unsafe impl<T, U> Send for Cow<'_, T, U>
540where
541 U: Capacity,
542 T: Beef + Sync + ?Sized,
543 T::Owned: Send,
544{
545}
546
547impl<T, U> Unpin for Cow<'_, T, U>
548where
549 U: Capacity,
550 T: Beef + ?Sized,
551 T::Owned: Unpin,
552{
553}