1#![no_std]
9
10#[cfg(feature = "alloc")]
11extern crate alloc;
12
13mod borrow;
14pub use borrow::{BorrowAsIs, BorrowMutAsIs, Owned, ToOwnedMut};
15
16#[cfg_attr(feature = "alloc", doc(no_inline))]
17pub use borrow::ToOwned;
18
19mod is;
20mod is_cow;
21mod is_mut;
22
23pub use is::Is;
24pub use is_cow::IsCow;
25pub use is_mut::IsMut;
26
27mod foreign;
28pub use foreign::{StringStub, VecStub};
29
30#[cfg(test)]
31mod tests;
32
33#[cfg(feature = "alloc")]
34use alloc::borrow::Cow;
35
36use core::borrow::{Borrow, BorrowMut};
37
38pub trait AsIs: Sized + BorrowAsIs {
42 #[allow(clippy::wrong_self_convention)]
46 fn as_is<'a>(self) -> Is<'a, Self::Is>
47 where
48 Self: 'a;
49
50 fn into_is<'a, B>(self) -> Is<'a, B>
54 where
55 Self: 'a,
56 Self::Is: BorrowMut<B>,
57 B: ?Sized + ToOwned<Owned = Owned<Self>>,
58 {
59 match self.as_is() {
60 Is::Owned(x) => Is::Owned(x),
61 Is::Borrowed(x) => Is::Borrowed(x.borrow()),
62 Is::MutBorrowed(x) => Is::MutBorrowed(x.borrow_mut()),
63 }
64 }
65
66 fn into_is_cow<'a, B>(self) -> IsCow<'a, B>
70 where
71 Self: 'a,
72 Self::Is: Borrow<B>,
73 B: ?Sized + ToOwned<Owned = Owned<Self>>,
74 {
75 match self.as_is() {
76 Is::Owned(x) => IsCow::Owned(x),
77 Is::Borrowed(x) => IsCow::Borrowed(x.borrow()),
78 Is::MutBorrowed(x) => IsCow::Borrowed((*x).borrow()),
79 }
80 }
81
82 fn try_into_is_mut<'a, B>(self) -> Result<IsMut<'a, B>, Is<'a, Self::Is>>
91 where
92 Self: 'a,
93 Self::Is: BorrowMut<B>,
94 B: ?Sized + ToOwned<Owned = Owned<Self>>,
95 {
96 match self.as_is() {
97 Is::Owned(x) => Ok(IsMut::Owned(x)),
98 Is::Borrowed(x) => Err(Is::Borrowed(x)),
99 Is::MutBorrowed(x) => Ok(IsMut::MutBorrowed(x.borrow_mut())),
100 }
101 }
102
103 fn try_into_owned<'a>(self) -> Result<Owned<Self>, Is<'a, Self::Is>>
111 where
112 Self: 'a,
113 {
114 match self.as_is() {
115 Is::Owned(x) => Ok(x),
116 Is::Borrowed(x) => Err(Is::Borrowed(x)),
117 Is::MutBorrowed(x) => Err(Is::MutBorrowed(x)),
118 }
119 }
120
121 #[cfg(feature = "alloc")]
126 fn into_cow<'a, B>(self) -> Cow<'a, B>
127 where
128 Self: 'a,
129 Self::Is: Borrow<B>,
130 B: ?Sized + ToOwned<Owned = Owned<Self>>,
131 {
132 match self.as_is() {
133 Is::Owned(x) => Cow::Owned(x),
134 Is::Borrowed(x) => Cow::Borrowed(x.borrow()),
135 Is::MutBorrowed(x) => Cow::Borrowed((*x).borrow()),
136 }
137 }
138}
139
140impl<T> AsIs for &T
141where
142 Self: Borrow<T::Is>,
143 T: ?Sized + BorrowAsIs,
144{
145 fn as_is<'a>(self) -> Is<'a, T::Is>
146 where
147 Self: 'a,
148 {
149 match self.borrow_or_clone() {
150 IsCow::Owned(x) => Is::Owned(x),
151 IsCow::Borrowed(x) => Is::Borrowed(x),
152 }
153 }
154}
155
156impl<T> AsIs for &mut T
157where
158 Self: Borrow<T::Is>,
159 T: ?Sized + BorrowMutAsIs,
160{
161 fn as_is<'a>(self) -> Is<'a, T::Is>
162 where
163 Self: 'a,
164 {
165 match self.borrow_or_clone() {
166 IsCow::Owned(x) => Is::Owned(x),
167 IsCow::Borrowed(_) => Is::MutBorrowed(self.borrow_mut()),
168 }
169 }
170}
171
172pub trait AsIsMut: AsIs + BorrowMutAsIs {
176 #[allow(clippy::wrong_self_convention)]
186 fn as_is_mut<'a>(self) -> IsMut<'a, Self::Is>
187 where
188 Self: 'a,
189 {
190 match self.as_is() {
191 Is::Owned(x) => IsMut::Owned(x),
192 Is::Borrowed(_) => {
193 panic!("Is::Borrowed variant returned from an AsIsMut type")
194 }
195 Is::MutBorrowed(x) => IsMut::MutBorrowed(x),
196 }
197 }
198
199 fn into_is_mut<'a, B>(self) -> IsMut<'a, B>
203 where
204 Self: 'a,
205 Self::Is: BorrowMut<B>,
206 B: ?Sized + ToOwned<Owned = Owned<Self>>,
207 {
208 match self.as_is_mut() {
209 IsMut::Owned(x) => IsMut::Owned(x),
210 IsMut::MutBorrowed(x) => IsMut::MutBorrowed(x.borrow_mut()),
211 }
212 }
213}
214
215impl<T> AsIsMut for T where Self: AsIs + BorrowMutAsIs {}