1#![cfg_attr(not(feature = "std"), no_std)]
104
105use core::{
106 cmp::Ordering,
107 fmt::{self, Debug, Formatter},
108 hash::{Hash, Hasher},
109 marker::PhantomData,
110};
111
112pub trait Borrow<'a, T>
117where
118 T: for<'b> BorrowHkt<'b>,
119{
120 fn borrow<'b>(&'a self) -> Borrowed<'b, T>
122 where
123 'a: 'b;
124}
125
126impl<'a> Borrow<'a, BorrowString> for &str {
127 fn borrow<'b>(&'a self) -> Borrowed<'b, BorrowString>
128 where
129 'a: 'b,
130 {
131 self
132 }
133}
134
135#[cfg(feature = "std")]
136impl<'a> Borrow<'a, BorrowString> for String {
137 fn borrow<'b>(&'a self) -> Borrowed<'b, BorrowString>
138 where
139 'a: 'b,
140 {
141 self
142 }
143}
144
145pub trait BorrowHkt<'a> {
148 type T;
150}
151
152pub struct BorrowString;
154
155impl<'a> BorrowHkt<'a> for BorrowString {
156 type T = &'a str;
157}
158
159pub type Borrowed<'a, T> = <T as BorrowHkt<'a>>::T;
161
162pub trait BorrowMut<'a, T>: Borrow<'a, T>
167where
168 T: for<'b> BorrowMutHkt<'b>,
169{
170 fn borrow_mut<'b>(&'a mut self) -> BorrowedMut<'b, T>
172 where
173 'a: 'b;
174}
175
176pub trait BorrowMutHkt<'a>: BorrowHkt<'a> {
179 type T;
181}
182
183pub type BorrowedMut<'a, T> = <T as BorrowMutHkt<'a>>::T;
185
186pub trait ToOwned: Sized {
192 type Owned;
194
195 fn to_owned(&self) -> Self::Owned;
197
198 fn into_owned(self) -> Self::Owned {
200 self.to_owned()
201 }
202}
203
204#[cfg(feature = "std")]
205impl ToOwned for &str {
206 type Owned = String;
207
208 fn to_owned(&self) -> Self::Owned {
209 std::borrow::ToOwned::to_owned(*self)
210 }
211}
212
213#[cfg(feature = "std")]
214impl ToOwned for String {
215 type Owned = String;
216
217 fn to_owned(&self) -> Self::Owned {
218 self.clone()
219 }
220
221 fn into_owned(self) -> Self::Owned {
222 self
223 }
224}
225
226#[cfg(feature = "std")]
227impl<T> ToOwned for std::borrow::Cow<'_, T>
228where
229 T: std::borrow::ToOwned + 'static,
230 T::Owned: Clone,
231{
232 type Owned = std::borrow::Cow<'static, T>;
233
234 fn to_owned(&self) -> std::borrow::Cow<'static, T> {
235 let owned = match self {
236 Self::Borrowed(x) => T::to_owned(x),
237 Self::Owned(x) => x.clone(),
238 };
239
240 std::borrow::Cow::Owned(owned)
241 }
242
243 fn into_owned(self) -> std::borrow::Cow<'static, T> {
244 let owned = match self {
245 Self::Borrowed(x) => T::to_owned(x),
246 Self::Owned(x) => x,
247 };
248
249 std::borrow::Cow::Owned(owned)
250 }
251}
252
253pub enum Cow<'a, T>
269where
270 T: Cowable,
271{
272 Borrowed(CowableBorrowed<'a, T>),
274
275 Owned(CowableOwned<T>),
277}
278
279impl<'a, T> Cow<'a, T>
280where
281 T: Cowable,
282{
283 pub fn borrowed(borrowed: impl Into<CowableBorrowed<'a, T>>) -> Self {
285 Self::Borrowed(borrowed.into())
286 }
287
288 pub fn owned(owned: impl Into<CowableOwned<T>>) -> Self {
290 Self::Owned(owned.into())
291 }
292
293 pub fn is_borrowed(&self) -> bool {
295 matches!(self, Self::Borrowed(_))
296 }
297
298 pub fn is_owned(&self) -> bool {
300 matches!(self, Self::Owned(_))
301 }
302
303 pub fn unwrap_borrowed(self) -> CowableBorrowed<'a, T> {
305 match self {
306 Self::Borrowed(x) => x,
307 Self::Owned(_) => panic!("Cow contains owned data"),
308 }
309 }
310
311 pub fn unwrap_owned(self) -> CowableOwned<T> {
313 match self {
314 Self::Borrowed(_) => panic!("Cow contains borrowed data"),
315 Self::Owned(x) => x,
316 }
317 }
318}
319
320impl<'a, T> Cow<'a, T>
321where
322 T: Cowable,
323 CowableBorrowed<'a, T>: ToOwned<Owned = CowableOwned<T>>,
324{
325 pub fn to_mut(&mut self) -> &mut CowableOwned<T> {
329 match self {
330 Self::Borrowed(x) => {
331 *self = Cow::Owned(x.to_owned());
333
334 match self {
335 Self::Borrowed(_) => unreachable!(),
336 Self::Owned(x) => x,
337 }
338 }
339 Self::Owned(x) => x,
340 }
341 }
342
343 pub fn into_inner(self) -> CowableOwned<T> {
346 match self {
347 Self::Borrowed(x) => x.into_owned(),
348 Self::Owned(x) => x,
349 }
350 }
351}
352
353impl<'a, T> Borrow<'a, BorrowCow<T>> for Cow<'a, T>
354where
355 T: Cowable,
356 CowableBorrowed<'a, T>: Borrow<'a, T::BorrowHkt>,
357 CowableOwned<T>: Borrow<'a, T::BorrowHkt>,
358{
359 fn borrow<'b>(&'a self) -> Borrowed<'b, BorrowCow<T>>
360 where
361 'a: 'b,
362 {
363 match self {
364 Self::Borrowed(x) => Cow::Borrowed(x.borrow()),
365 Self::Owned(x) => Cow::Borrowed(x.borrow()),
366 }
367 }
368}
369
370impl<'a, T> ToOwned for Cow<'a, T>
371where
372 T: Cowable,
373 CowableBorrowed<'a, T>: ToOwned<Owned = CowableOwned<T>>,
374 CowableOwned<T>: Clone,
375{
376 type Owned = Cow<'static, T>;
377
378 fn to_owned(&self) -> Cow<'static, T> {
379 match self {
380 Self::Borrowed(x) => Cow::Owned(x.to_owned()),
381 Self::Owned(x) => Cow::Owned(x.clone()),
382 }
383 }
384
385 fn into_owned(self) -> Cow<'static, T> {
386 match self {
387 Self::Borrowed(x) => Cow::Owned(x.into_owned()),
388 Self::Owned(x) => Cow::Owned(x),
389 }
390 }
391}
392
393impl<'a, T> Clone for Cow<'a, T>
394where
395 T: Cowable,
396 CowableBorrowed<'a, T>: Clone,
397 CowableOwned<T>: Clone,
398{
399 fn clone(&self) -> Self {
400 match self {
401 Self::Borrowed(x) => Self::Borrowed(x.clone()),
402 Self::Owned(x) => Self::Owned(x.clone()),
403 }
404 }
405}
406
407impl<'a, T> Copy for Cow<'a, T>
408where
409 T: Cowable,
410 CowableBorrowed<'a, T>: Copy,
411 CowableOwned<T>: Copy,
412{
413}
414
415impl<'a, T> Debug for Cow<'a, T>
416where
417 T: Cowable,
418 CowableBorrowed<'a, T>: Debug,
419 CowableOwned<T>: Debug,
420{
421 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
422 match self {
423 Self::Borrowed(x) => x.fmt(f),
424 Self::Owned(x) => x.fmt(f),
425 }
426 }
427}
428
429impl<T> Default for Cow<'_, T>
430where
431 T: Cowable,
432 CowableOwned<T>: Default,
433{
434 fn default() -> Self {
435 Self::Owned(Default::default())
436 }
437}
438
439impl<'a, T> Hash for Cow<'a, T>
440where
441 T: Cowable,
442 CowableBorrowed<'a, T>: Hash,
443 CowableOwned<T>: Hash,
444{
445 fn hash<H: Hasher>(&self, state: &mut H) {
446 match self {
447 Self::Borrowed(x) => x.hash(state),
448 Self::Owned(x) => x.hash(state),
449 }
450 }
451}
452
453impl<'a, T> PartialEq<Cow<'a, T>> for Cow<'a, T>
454where
455 T: Cowable,
456 CowableBorrowed<'a, T>: PartialEq + PartialEq<CowableOwned<T>>,
457 CowableOwned<T>: PartialEq + PartialEq<CowableBorrowed<'a, T>>,
458{
459 fn eq(&self, other: &Cow<'a, T>) -> bool {
460 match (self, other) {
461 (Self::Borrowed(a), Self::Borrowed(b)) => a.eq(b),
462 (Self::Borrowed(a), Self::Owned(b)) => a.eq(b),
463 (Self::Owned(a), Self::Borrowed(b)) => a.eq(b),
464 (Self::Owned(a), Self::Owned(b)) => a.eq(b),
465 }
466 }
467}
468
469impl<'a, T> Eq for Cow<'a, T>
470where
471 T: Cowable,
472 CowableBorrowed<'a, T>: Eq + PartialEq<CowableOwned<T>>,
473 CowableOwned<T>: Eq + PartialEq<CowableBorrowed<'a, T>>,
474{
475}
476
477impl<'a, T> PartialOrd for Cow<'a, T>
478where
479 T: Cowable,
480 CowableBorrowed<'a, T>: PartialOrd + PartialOrd<CowableOwned<T>>,
481 CowableOwned<T>: PartialOrd + PartialOrd<CowableBorrowed<'a, T>>,
482{
483 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
484 match (self, other) {
485 (Self::Borrowed(a), Self::Borrowed(b)) => a.partial_cmp(b),
486 (Self::Borrowed(a), Self::Owned(b)) => a.partial_cmp(b),
487 (Self::Owned(a), Self::Borrowed(b)) => a.partial_cmp(b),
488 (Self::Owned(a), Self::Owned(b)) => a.partial_cmp(b),
489 }
490 }
491
492 fn ge(&self, other: &Self) -> bool {
493 match (self, other) {
494 (Self::Borrowed(a), Self::Borrowed(b)) => a.ge(b),
495 (Self::Borrowed(a), Self::Owned(b)) => a.ge(b),
496 (Self::Owned(a), Self::Borrowed(b)) => a.ge(b),
497 (Self::Owned(a), Self::Owned(b)) => a.ge(b),
498 }
499 }
500
501 fn gt(&self, other: &Self) -> bool {
502 match (self, other) {
503 (Self::Borrowed(a), Self::Borrowed(b)) => a.gt(b),
504 (Self::Borrowed(a), Self::Owned(b)) => a.gt(b),
505 (Self::Owned(a), Self::Borrowed(b)) => a.gt(b),
506 (Self::Owned(a), Self::Owned(b)) => a.gt(b),
507 }
508 }
509
510 fn le(&self, other: &Self) -> bool {
511 match (self, other) {
512 (Self::Borrowed(a), Self::Borrowed(b)) => a.le(b),
513 (Self::Borrowed(a), Self::Owned(b)) => a.le(b),
514 (Self::Owned(a), Self::Borrowed(b)) => a.le(b),
515 (Self::Owned(a), Self::Owned(b)) => a.le(b),
516 }
517 }
518
519 fn lt(&self, other: &Self) -> bool {
520 match (self, other) {
521 (Self::Borrowed(a), Self::Borrowed(b)) => a.lt(b),
522 (Self::Borrowed(a), Self::Owned(b)) => a.lt(b),
523 (Self::Owned(a), Self::Borrowed(b)) => a.lt(b),
524 (Self::Owned(a), Self::Owned(b)) => a.lt(b),
525 }
526 }
527}
528
529impl<'a, T> Ord for Cow<'a, T>
530where
531 T: Cowable,
532 CowableBorrowed<'a, T>: Ord + PartialOrd<CowableOwned<T>>,
533 CowableOwned<T>: Ord + PartialOrd<CowableBorrowed<'a, T>>,
534{
535 fn cmp(&self, other: &Self) -> Ordering {
536 match (self, other) {
537 (Self::Borrowed(a), Self::Borrowed(b)) => a.cmp(b),
538 (Self::Borrowed(a), Self::Owned(b)) => a.partial_cmp(b).unwrap(),
539 (Self::Owned(a), Self::Borrowed(b)) => a.partial_cmp(b).unwrap(),
540 (Self::Owned(a), Self::Owned(b)) => a.cmp(b),
541 }
542 }
543}
544
545pub struct BorrowCow<T>(PhantomData<T>);
547
548impl<'a, T> BorrowHkt<'a> for BorrowCow<T>
549where
550 T: Cowable,
551{
552 type T = Cow<'a, T>;
553}
554
555pub trait Cowable {
560 type BorrowHkt: for<'a> BorrowHkt<'a>;
562
563 type Owned;
565}
566
567impl<B, O> Cowable for B
570where
571 B: for<'a> BorrowHkt<'a>,
572 for<'a> <B as BorrowHkt<'a>>::T: ToOwned<Owned = O>,
573{
574 type BorrowHkt = B;
575 type Owned = O;
576}
577
578pub type CowableBorrowed<'a, T> = Borrowed<'a, <T as Cowable>::BorrowHkt>;
580
581pub type CowableOwned<T> = <T as Cowable>::Owned;
583
584macro_rules! simple_type {
586 ($ty:ty) => {
587 impl<'a> Borrow<'a, $ty> for $ty {
588 fn borrow<'b>(&'a self) -> Borrowed<'b, $ty>
589 where
590 'a: 'b,
591 {
592 *self
593 }
594 }
595
596 impl BorrowHkt<'_> for $ty {
597 type T = $ty;
598 }
599
600 impl ToOwned for $ty {
601 type Owned = $ty;
602
603 fn to_owned(&self) -> Self::Owned {
604 *self
605 }
606 }
607 };
608}
609
610simple_type!(());
611simple_type!(bool);
612simple_type!(char);
613simple_type!(i8);
614simple_type!(i16);
615simple_type!(i32);
616simple_type!(i64);
617simple_type!(i128);
618simple_type!(isize);
619simple_type!(u8);
620simple_type!(u16);
621simple_type!(u32);
622simple_type!(u64);
623simple_type!(u128);
624simple_type!(usize);
625simple_type!(f32);
626simple_type!(f64);