1use crate::{IsCow, IsMut};
2use core::borrow::{Borrow, BorrowMut};
3
4pub trait BorrowAsIs: Borrow<Self::Is> {
8 type Is: ?Sized + BorrowAsIs<Is = Self::Is> + ToOwned;
10
11 fn borrow_as_is(&self) -> &Self::Is {
15 self.borrow()
16 }
17
18 fn borrow_or_clone<B>(&self) -> IsCow<'_, B>
21 where
22 Self::Is: Borrow<B>,
23 B: ?Sized + ToOwned<Owned = Owned<Self>>,
24 {
25 IsCow::Borrowed(self.borrow().borrow())
26 }
27}
28
29impl<T> BorrowAsIs for &T
30where
31 Self: Borrow<T::Is>,
32 T: ?Sized + BorrowAsIs,
33{
34 type Is = T::Is;
35
36 fn borrow_or_clone<B>(&self) -> IsCow<'_, B>
37 where
38 Self::Is: Borrow<B>,
39 B: ?Sized + ToOwned<Owned = Owned<Self>>,
40 {
41 (**self).borrow_or_clone()
42 }
43}
44
45impl<T> BorrowAsIs for &mut T
46where
47 Self: Borrow<T::Is>,
48 T: ?Sized + BorrowAsIs,
49{
50 type Is = T::Is;
51
52 fn borrow_or_clone<B>(&self) -> IsCow<'_, B>
53 where
54 Self::Is: Borrow<B>,
55 B: ?Sized + ToOwned<Owned = Owned<Self>>,
56 {
57 (**self).borrow_or_clone()
58 }
59}
60
61pub trait BorrowMutAsIs: BorrowAsIs + BorrowMut<Self::Is> {
65 fn borrow_mut_as_is(&mut self) -> &mut Self::Is {
69 self.borrow_mut()
70 }
71
72 fn borrow_mut_or_clone<B>(&mut self) -> IsMut<'_, B>
76 where
77 Self::Is: BorrowMut<B>,
78 B: ?Sized + ToOwned<Owned = Owned<Self>>,
79 {
80 match self.borrow_or_clone() {
81 IsCow::Owned(x) => IsMut::Owned(x),
82 IsCow::Borrowed(_) => IsMut::MutBorrowed(self.borrow_mut().borrow_mut()),
83 }
84 }
85}
86
87impl<T> BorrowMutAsIs for T where T: ?Sized + BorrowAsIs + BorrowMut<Self::Is> {}
88
89#[doc(no_inline)]
90#[cfg(feature = "alloc")]
91pub use alloc::borrow::ToOwned;
92
93#[cfg(not(feature = "alloc"))]
100pub trait ToOwned {
101 type Owned: Borrow<Self>;
103}
104
105#[cfg(not(feature = "alloc"))]
106impl<T> ToOwned for T
107where
108 T: Clone,
109{
110 type Owned = T;
111}
112
113#[cfg_attr(
116 feature = "alloc",
117 doc = "[`ToOwned`]: https://doc.rust-lang.org/alloc/borrow/trait.ToOwned.html"
118)]
119#[cfg_attr(
120 feature = "alloc",
121 doc = "[`Owned`]: https://doc.rust-lang.org/1.65.0/alloc/borrow/trait.ToOwned.html#associatedtype.Owned"
122)]
123#[cfg_attr(not(feature = "alloc"), doc = "[`ToOwned`]: trait.ToOwned.html")]
124#[cfg_attr(
125 not(feature = "alloc"),
126 doc = "[`Owned`]: trait.ToOwned.html#associatedtype.Owned"
127)]
128pub trait ToOwnedMut: ToOwned<Owned = Self::OwnedMut> {
129 type OwnedMut: BorrowMut<Self>;
131}
132
133impl<T> ToOwnedMut for T
134where
135 T: ?Sized + ToOwned,
136 T::Owned: BorrowMut<T>,
137{
138 type OwnedMut = T::Owned;
139}
140
141#[cfg_attr(
145 feature = "alloc",
146 doc = "[`ToOwned`]: https://doc.rust-lang.org/alloc/borrow/trait.ToOwned.html"
147)]
148#[cfg_attr(not(feature = "alloc"), doc = "[`ToOwned`]: trait.ToOwned.html")]
149pub type Owned<T> = <<T as BorrowAsIs>::Is as ToOwned>::Owned;