as_is/
borrow.rs

1use crate::{IsCow, IsMut};
2use core::borrow::{Borrow, BorrowMut};
3
4/// Immutably borrows the primary borrow target as [`Is`].
5///
6/// [`Is`]: trait.BorrowAsIs.html#associatedtype.Is
7pub trait BorrowAsIs: Borrow<Self::Is> {
8    /// The primary borrow target.
9    type Is: ?Sized + BorrowAsIs<Is = Self::Is> + ToOwned;
10
11    /// Immutably borrows from `self` as [`Is`].
12    ///
13    /// [`Is`]: trait.BorrowAsIs.html#associatedtype.Is
14    fn borrow_as_is(&self) -> &Self::Is {
15        self.borrow()
16    }
17
18    /// Immutably borrows from `self` by default, but can be overridden to clone `self` if
19    /// appropriate.
20    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
61/// Mutably borrows the primary borrow target as [`Is`].
62///
63/// [`Is`]: trait.BorrowAsIs.html#associatedtype.Is
64pub trait BorrowMutAsIs: BorrowAsIs + BorrowMut<Self::Is> {
65    /// Mutably borrows from `self` as [`Is`].
66    ///
67    /// [`Is`]: trait.BorrowAsIs.html#associatedtype.Is
68    fn borrow_mut_as_is(&mut self) -> &mut Self::Is {
69        self.borrow_mut()
70    }
71
72    /// Mutably borrows from `self` by default, but clones `self` if [`self.borrow_or_clone()`] is overridden to clone `self`.
73    ///
74    /// [`self.borrow_or_clone()`]: trait.BorrowAsIs.html#method.borrow_or_clone
75    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/// An alternative to [`alloc::borrow::ToOwned`] available in a `no_std` environment.
94///
95/// Only associated type [`Owned`] is provided.
96///
97/// [`alloc::borrow::ToOwned`]: https://doc.rust-lang.org/alloc/borrow/trait.ToOwned.html
98/// [`Owned`]: trait.ToOwned.html#associatedtype.Owned
99#[cfg(not(feature = "alloc"))]
100pub trait ToOwned {
101    /// The resulting type after obtaining ownership.
102    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/// [`ToOwned`] types that can be mutably borrowed from [`Owned`].
114///
115#[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    /// The resulting type after obtaining ownership.
130    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/// The owned type associated through [`BorrowAsIs`] and [`ToOwned`].
142///
143/// [`BorrowAsIs`]: trait.BorrowAsIs.html
144#[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;