Trait borrowme::Borrow

source ·
pub trait Borrow {
    type Target<'a>
       where Self: 'a;

    // Required method
    fn borrow(&self) -> Self::Target<'_>;
}
Expand description

Borrow from self.

This works similarly to Borrow but allows borrowing compoundly from &self by defining a generic Target. This means it’s not just limited to returning an immediate reference to the borrowed value but can return something which receives lifetime parameters that borrows from self. This is called “compound borrowing” because it lets you return types which contains compound references.

It is recommended that you use borrow instead of importing this trait.


What about std::borrow::Borrow?

The Borrow trait as defined can’t perform compound borrows from &self. Because the borrow method immediately returns a reference to the borrowed type.

trait Borrow<Borrowed: ?Sized> {
    fn borrow(&self) -> &Borrowed;
}

This means that there is no way to implement something like Borrow<Word<'a>> because it’s required that we return a reference which doesn’t outlive 'a, something that can’t be satisfied from the call to &self.

struct Word<'a>(&'a str);
struct OwnedWord(String);

impl<'a> Borrow<Word<'a>> for OwnedWord {
    fn borrow(&self) -> &Word<'a> {
        &Word(self.0.as_str())
    }
}
error[E0515]: cannot return reference to temporary value
 --> src/borrow.rs:37:9
  |
9 |         &Word(self.0.as_str())
  |         ^---------------------
  |         ||
  |         |temporary value created here
  |         returns a reference to data owned by the current function

The solution implemented in this crate is to use a generic Target, with which we can implement borrow like this:

use borrowme::Borrow;

impl Borrow for OwnedWord {
    type Target<'a> = Word<'a>;

    fn borrow(&self) -> Self::Target<'_> {
        Word(self.0.as_str())
    }
}

A catch here is that Borrow can only be implemented once for each time, compared to Borrow<T>. But for our purposes this is fine. This crate is primarily intended to work with two symmetrical types and any deviation from that pattern can be handled by customizing the behavior of the #[borrowme] attribute.

Required Associated Types§

source

type Target<'a> where Self: 'a

Required Methods§

source

fn borrow(&self) -> Self::Target<'_>

Borrow from self.

Implementations on Foreign Types§

source§

impl Borrow for PathBuf

§

type Target<'a> where Self: 'a = &'a Path

source§

fn borrow(&self) -> Self::Target<'_>

source§

impl<T> Borrow for BTreeSet<T>where T: Borrow, for<'a> T::Target<'a>: PartialOrd + Ord + Eq,

§

type Target<'a> where T: 'a = BTreeSet<<T as Borrow>::Target<'a>, Global>

source§

fn borrow(&self) -> Self::Target<'_>

source§

impl Borrow for String

§

type Target<'a> = &'a str

source§

fn borrow(&self) -> Self::Target<'_>

source§

impl<B> Borrow for Cow<'static, B>where B: ?Sized + ToOwned,

§

type Target<'a> = Cow<'a, B>

source§

fn borrow(&self) -> Self::Target<'_>

source§

impl<T> Borrow for Option<T>where T: Borrow,

§

type Target<'a> where T: 'a = Option<<T as Borrow>::Target<'a>>

source§

fn borrow(&self) -> Self::Target<'_>

source§

impl<T> Borrow for [T]

§

type Target<'a> where T: 'a = &'a [T]

source§

fn borrow(&self) -> Self::Target<'_>

source§

impl Borrow for CString

§

type Target<'a> where Self: 'a = &'a CStr

source§

fn borrow(&self) -> Self::Target<'_>

source§

impl<K, V> Borrow for HashMap<K, V>where K: Borrow, V: Borrow, for<'a> K::Target<'a>: Hash + Eq,

§

type Target<'a> where K: 'a, V: 'a = HashMap<<K as Borrow>::Target<'a>, <V as Borrow>::Target<'a>, RandomState>

source§

fn borrow(&self) -> Self::Target<'_>

source§

impl<T> Borrow for Vec<T>where T: Borrow,

§

type Target<'a> where T: 'a = Vec<<T as Borrow>::Target<'a>, Global>

source§

fn borrow(&self) -> Self::Target<'_>

source§

impl Borrow for OsString

§

type Target<'a> where Self: 'a = &'a OsStr

source§

fn borrow(&self) -> Self::Target<'_>

source§

impl<T> Borrow for LinkedList<T>where T: Borrow,

§

type Target<'a> where T: 'a = LinkedList<<T as Borrow>::Target<'a>, Global>

source§

fn borrow(&self) -> Self::Target<'_>

source§

impl<K, V> Borrow for BTreeMap<K, V>where K: Borrow, V: Borrow, for<'a> K::Target<'a>: PartialOrd + Ord + Eq,

§

type Target<'a> where K: 'a, V: 'a = BTreeMap<<K as Borrow>::Target<'a>, <V as Borrow>::Target<'a>, Global>

source§

fn borrow(&self) -> Self::Target<'_>

source§

impl<T: ?Sized> Borrow for Box<T>

§

type Target<'a> where T: 'a = &'a T

source§

fn borrow(&self) -> Self::Target<'_>

source§

impl<T> Borrow for HashSet<T>where T: Borrow, for<'a> T::Target<'a>: Hash + Eq,

§

type Target<'a> where T: 'a = HashSet<<T as Borrow>::Target<'a>, RandomState>

source§

fn borrow(&self) -> Self::Target<'_>

Implementors§