So, I wrote a little struct for keeping track of something that can be borrowed or owned:
pub enum Has<'a, B> where B: 'a {
Borrowed(&'a B),
Owned(B),
}
impl<'a, B> Has<'a, B> {
fn have(&self) -> &B {
match *self {
Has::Borrowed(b) => b,
Has::Owned(ref b) => b,
}
}
fn take(self) -> Option<B> {
match self {
Has::Borrowed(_) => None,
Has::Owned(b) => Some(b),
}
}
}
With impls for Deref
, AsRef
, Borrow
, Display
, Debug
, etc. just as you'd expect. Among other things, it's useful for returning a member that might be mutated, while avoiding allocation if it's not:
pub fn fancy_value(&self) -> Has<SomethingNotClone> {
if self.value.is_fancy() {
Borrowed(&self.value)
} else {
Owned(self.value.make_fancy_version())
}
}
This is very much like Cow
, except that it can operate on non-Clone
/ non-ToOwner
targets, so long as they're Sized
.
First question: Is this problem already solved / is there something already like this somewhere? I looked around through the Rust API docs and book, did some web searches, but found nothing like this.
Secondly: Is this worth adding to std? It seems like this is a pretty handy thing to have, although there's a lot of overlap with Cow
.