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:
- 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.
- 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
}
}