If I have a function that needs to borrow a value, but I want to allow the caller to pass either a reference to the value or an owned value, I can of course do this:
fn foo(bar: impl Borrow<Bar>) {
bar.borrow();
}
But if I'm in the opposite situation where I have a function that needs to take ownership of a value, but I want to allow the caller to pass either a reference (which will be cloned) or an owned value which will be taken as is, I don't know of a general way to do this?
Of course, with types created by me I can implement From and take impl Into<Bar> but I can't do this with external types, whereas Borrow works without an explicit implementation as it has the blanket implementation.
It seems to me that if a type implements Clone then there should be a blanket implementation, either using Into, or some other trait that would make this possible.
As a side question, not meaning to distract from the above, but why does Borrow exist when Into exists? can't there just be a blanket implementation for Into<&T>?
For types like String and PathBuf, impl Into<T> works fine.
That's tricky. Rust doesn't allow overlapping implementations, and doesn't have specialization (yet), so if stdlib provided a blanket implementation, there would be no other way to provide a custom conversion.
In general, I think an interface like this would be surprising, as passing by value would be significantly cheaper for non-trivialize objects than passing by reference would be.
I think the "right" approach is to take an owned value, and let the caller perform the clone if appropriate and necessary.