1

I'm trying to make a generic method interface that takes several ref-types and tries to save a clone if possible. I have two issues:

  1. There are a lot of traits about referencing & such, but I'm not sure how to apply them so that you can tell btwn value, mut value, ref, mut ref in a single generic function.
  2. Is there a best practice for clone if needed? I've played with Cow, From/Into, ToOwned, AsRef, Deref, more, but I just can't find the sensible way to do it.

Cow has the idea of what I want, but if I expose Cow on input, I can't use Cow::from without implementing it and Cow::Owned/Borrowed defeats most of the purpose. And I can't figure out without exposing Cow input. From/Into is almost perfect, but I can't get the generics to work. I also tried splitting the functions into separate traits and implementing, but the compiler can't choose between them.

I have a basic demo below. I have control over the Bar interface as well, if that is needed to get a decent interface, but I'd be surprised if there wasn't a simple way to essentially perfect forward the arguments.

How does Rust provide move semantics? is similar, but didn't solve the issue.

struct Foo {
    x: i32
}
impl Foo {
    // Move bar in; no clone, return original
    pub fn add<T: Bar>(&self, mut bar: T) -> T {
        bar.plus(self.x);
        bar
    }
    // bar immutable or reference; clone and return
    pub fn add<T: Bar>(&self, bar: T | &T | &mut T) -> T {
        let mut newbar = bar.clone();
        newbar.plus(self.x);
        newbar
    }
}
Joe Mitchell
  • 45
  • 1
  • 8
  • 1
    Can you expand on what your problems with using `Cow` are? Why do you not want to expose `Cow` as an input, and why is `Cow::to_mut` not good for your use case? – Isaac van Bakel May 15 '19 at 11:11

0 Answers0