pub trait GenericCow where
    Self: Sized,
    Self: Borrow<Self::Borrowed>,
    Self: Deref<Target = Self::Borrowed>, 
{ type Borrowed: ?Sized + ToOwned; fn into_owned(self) -> <Self::Borrowed as ToOwned>::Owned; }
Expand description

Generalized Cow

The trait GenericCow<Borrowed = B> is a generalization of Cow<'_, B> and is implemented for:


use deref_owned::GenericCow;
use std::borrow::Borrow;

fn generic_fn(arg: impl GenericCow<Borrowed = str>) {
    let reference: &str = &*arg; // or: arg.borrow()
    assert_eq!(reference, "Hello");
    let owned: String = arg.into_owned();
    assert_eq!(owned, "Hello".to_string());

Design considerations

Note that the trait definition contains some redundancy. Either

could have been omitted. Both have been included to simplify syntax when using the trait:

  • Including the associated type allows specifying the borrowed type in bounds easily without having to add an extra Deref bound (which would require std::ops::Deref being in scope).
  • Using Deref as supertrait ensures that it’s easy to go to the borrowed type using the operator combination “&*” instead of having to use the horrible syntax “Borrow::<<Type as GenericCow>::Borrowed>::borrow(&value)” when type inference would fail when simply using .borrow(). Moreover, deref coercion improves ergonomics.

Required Associated Types

Borrowed type

This associated type is identical to <Self as Deref>::Target, which causes some redundancy when implementing the trait but simplifies syntax when using the trait (Deref doesn’t need to be in scope to specify the borrowed type).

Required Methods

Convert into owned type

Opposed to ToOwned::to_owned, this method consumes the receiver, which allows avoiding unnecessary clones in some cases. I.e. using this method on an Owned value (or on a Cow::Owned enum variant) will simply unwrap it. In case of using the Owned struct of this crate (instead of Cow), this operation is zero-cost.

Implementations on Foreign Types