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.

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl Borrow for CString

§

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

source§

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

source§

impl Borrow for String

§

type Target<'a> = &'a str

source§

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

source§

impl Borrow for OsString

§

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

source§

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

source§

impl Borrow for PathBuf

§

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

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<K, V> Borrow for BTreeMap<K, V>
where K: Borrow, V: Borrow, for<'a, 'a, 'a> K::Target<'a>: PartialOrd + Ord + Eq,

§

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

source§

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

source§

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

§

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

source§

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

source§

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

§

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

source§

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

source§

impl<T> Borrow for [T]

§

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

source§

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

source§

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

§

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

source§

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

source§

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

§

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

source§

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

source§

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

§

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

source§

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

source§

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

§

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

source§

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

source§

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

§

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

source§

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

Implementors§