1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
#[cfg(feature = "std")]
mod std;
/// Convert to owned.
///
/// This works similarly to [`ToOwned`][::std::borrow::ToOwned] with a few
/// relaxed constaints. It is recommended that you use
/// [`to_owned`][crate::to_owned()] instead of importing this trait.
///
/// <br>
///
/// # What about `std::borrow::ToOwned`?
///
/// [`std::borrow::ToOwned`] a trait which requires that the resulting `Owned`
/// type can be borrowed back into a reference of itself. This can't be
/// implemented for compound borrowing (See
/// [`borrowme::Borrow`][crate::Borrow]). So because we can't implement
/// [`std::borrow::Borrow<Self>`][::std::borrow::Borrow], we can't implemented
/// [`std::borrow::ToOwned`] either.
///
/// To showcase this, let's try to implement [`std::borrow::ToOwned`] for a type
/// which has a lifetime parameter:
///
/// [`std::borrow::ToOwned`]: ::std::borrow::ToOwned
///
/// ```rust,no_run
/// # use borrowme::ToOwned;
/// struct Word<'a>(&'a str);
/// struct OwnedWord(String);
///
/// impl ToOwned for Word<'_> {
/// type Owned = OwnedWord;
///
/// fn to_owned(&self) -> OwnedWord {
/// OwnedWord(String::from(self.0))
/// }
/// }
/// ```
///
/// ```text
/// error[E0277]: the trait bound `OwnedWord: std::borrow::Borrow<Word<'_>>` is not satisfied
/// --> src/lib.rs:27:18
/// |
/// 11 | type Owned = OwnedWord;
/// | ^^^^^^^^^ the trait `std::borrow::Borrow<Word<'_>>` is not implemented for `OwnedWord`
/// ```
///
/// So in this crate we define a different [`ToOwned`] trait which does not
/// require the produced value to be [`Borrow<Self>`][::std::borrow::Borrow].
///
/// With this, we can implement the conversion:
///
/// ```
/// # struct Word<'a>(&'a str);
/// # struct OwnedWord(String);
/// use borrowme::ToOwned;
///
/// impl ToOwned for Word<'_> {
/// type Owned = OwnedWord;
///
/// fn to_owned(&self) -> OwnedWord {
/// OwnedWord(self.0.to_string())
/// }
/// }
/// ```
pub trait ToOwned {
/// The owned type this is being converted to.
type Owned;
/// Perform a covnersion from a reference to owned value.
fn to_owned(&self) -> Self::Owned;
}
impl<T> ToOwned for &T
where
T: ?Sized + ToOwned,
{
type Owned = T::Owned;
#[inline]
fn to_owned(&self) -> Self::Owned {
T::to_owned(*self)
}
}