0

I have some structs which could either be given a mutable slice or a Vec to own. The best solution I've been able to come up with is to make a simple enum which can contain a slice or a Vec and then Derefs to a slice.

pub enum DataSource<'a, T> {
    Borrowed(&'a mut [T]),
    Owned(Vec<T>),
}

impl<T> Deref for DataSource<'_, T> {
    type Target = [T];
    fn deref(&self) -> &Self::Target {
        match self {
            DataSource::Borrowed(val) => val,
            DataSource::Owned(val) => val,
        }
    }
}

impl<T> DerefMut for DataSource<'_, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        match self {
            DataSource::Borrowed(val) => val,
            DataSource::Owned(val) => val,
        }
    }
}

This seems quite simple (even if it's not recommended to implement Deref for your own types) so I'm sure I'm not the first person to think of this.

Is there something like this already in the Rust std library, or is there a crate which provides it?

curiousdannii
  • 1,658
  • 1
  • 25
  • 40
  • 2
    I think you'll have to do it yourself, but there is prior work: The standard [`Cow`](https://doc.rust-lang.org/std/borrow/enum.Cow.html) type is almost what you have but keeps an *immutable* and has different semantics in that the borrowed variant is *promoted* to the owned variant via `.to_owned()` when mutation is desired. The linked guidance against `Deref` is mostly to dissuade inheritance-seeking behavior, which this case is not. – kmdreko Jul 02 '23 at 03:56
  • deref on such struct look ok – Stargateur Jul 02 '23 at 07:23
  • I believe the reason this struct doesn't exist is because it's not that useful: `Cow` is useful when you need clone-on-write, but with mutable data you can always write. – Chayim Friedman Jul 02 '23 at 08:18

1 Answers1

1

either::Either implements Deref and DerefMut if both sides deref to the same type.

Jmb
  • 18,893
  • 2
  • 28
  • 55
  • This is subjective of course, but I would not use `Either` for this, are use it only when you need two types and there is completely no difference between their roles besides being two different types. – Chayim Friedman Jul 02 '23 at 08:19