either icon indicating copy to clipboard operation
either copied to clipboard

Alternative `Deref` implementations

Open peterjoel opened this issue 7 years ago • 1 comments

This might not go anywhere, but here seemed like the right place to open the conversation.

I think there is a need for a type that captures the possibility of being either owned or some kind of reference, but without requiring the ToOwned constraint of Cow.

Currently Either has this Deref impl:

impl<L, R> Deref for Either<L, R> 
where
    L: Deref,
    R: Deref<Target = L::Target>,

Which is nice for Either<&T, Box<T>> or even things like Either<Ref<'a, T>, Either<Rc<T>, Box<T>>> etc. But Deref isn't implemented for Either<T, &T> which is a shame, because Cow also won't work here unless T: ToOwned<Owned = T>, which it mostly isn't unless T: Clone. An impl for Either that would work there would look like this:

impl<L, R> Deref for Either<L, R> 
where
    R: Deref<Target = L>, 

But it can't co-exist with the current implementation.

A workaround is to introduce a newtype:

struct Own<T>(T);
impl<T> Deref for Own<T> {
     type Target = T;
     fn deref(&self) -> Self::Target {
          self.0
     }
}

So you can do now use Either<Own<T>, &T>.

I'm sure many other crates have rolled their own (though I didn't find any), but it would be better if there was one canonical way to do this. What's the best way to achieve that? Try to do something in either, some other crate or a completely new one?

peterjoel avatar Sep 19 '18 15:09 peterjoel

Borrow might work for you, except Either doesn't implement that, and I think it would be a breaking change to add that as a new blanket impl.

Besides, you might really want Deref, especially since the compiler will auto-deref in some cases. Then I think your Own is a reasonable solution. I don't think this problem is so specific to Either though, for the solution to belong in this crate.

cuviper avatar Sep 19 '18 17:09 cuviper