Consuming equivalent of ToOwned?


#1

I often find myself in a situation where my function needs to have an owned piece of data equivalent to one of the parameters, but some callers might not be willing to give up ownership of the data. Currently I just make the function take owned data (e.g. String), but that makes the call site quite cumbersome, since a client that doesn’t give up ownership of its data has to create copies manually.
Is there some idiomatic way to pass in arguments as either owned or borrowed, and transformed them into an owned type in the callee? ToOwned does almost that, except it creates a new copy of data that is already owned, instead of returning it as is.


#2

Yes! That is precisely what the Cow type is for :slight_smile:

Of course, Cow also clones if an owned object is needed, as that is the only way to turn a reference into an owned object if the owner is unable to give up ownership of the original.


#3

Into<String> may also be what you want.


#4

Doesn’t the Into trait allow cloning as well? IIRC the semantics were something along the lines of “allowed to do non-trivial (i.e. expensive) conversions, as long as they’re infallible”.


#5

Things that don’t have a string to give out will allocate a new one, which seems expected?


#6

Just FTR, I’m not saying it’s weird or anything :slight_smile:
I’m just acknowledging that cloning (or otherwise performing allocation) is generally the only avenue when going from borrow to an owned version of the borrowed object.

In a sense I suppose the traits are all sugar op top of that core strategy.


#7

This seems to be exactly what I wanted, thanks! It doesn’t say so explicitly in the documentation, but I assume that the generic impl From<T> for T in the documentation just returns self.
I guess Cow has the same semantics, but it comes with the kind of noisy interface that I’m trying to avoid here.


#8

Yup. There’s nothing else it can really do either.

One issue you may encounter with Into is you’ll need to provide the Into (or From) impls for types that don’t already have a conversion from &T to T. There’s no blanket impl that allows this for T: Clone, for example. But this is the best trait (AFAIK at least) for your usecase.