Is there to_owned for Options?

Hi! What's the best way to convert Option<&str> into Option<String>?

to_owned does not work, because it is not a reference. .cloned does not work because it does not changes the type.

.map(str::to_owned) works, but is not pretty :frowning:

I can't see any other way to do it currently :frowning:

It seems like Option should probably have an implementation of ToOwned, but the associated type constraints stop it from working, type Owned: Borrow<Self> is impossible for Option to implement.

But, like the .as_ref inherent method that is almost but not quite the same as the AsRef trait, Option could have an alternative added, hiding the ugliness away

impl<'a, T> Option<&'a T> where T: ToOwned {
    fn to_owned(&self) -> Option<T::Owned> {
        self.map(T::to_owned)
    }
}
1 Like

Yeah, I was thinking that maybe perhaps this method is missing... I wonder if someone should send a PR to rust :wink:

I would argue that the map is exactly what you want, and isn't long enough to justify its own method. Plus, option is a type with ownership, so to_owned isn't appropriate on it; you'd want inner_to_owned or something.

4 Likes

Is there still interest in this?
Was there ever a PR or issue opened?

I can't find any previous PRs or issues. This still seems like a reasonable addition, if someone wants to submit a PR for it.

1 Like

I think, I'll give this a shot and submit a PR.

1 Like

I've got a problem with the implementation:

Option is defined in the core library, but ToOwned is only part of the std library.
What should I do?

Clearly, ToOwned potentially needs heap allocation which core cannot rely on. This means that this method cannot be an inherent method of Option. Maybe write an extension trait? I'm not sure how common or how much frowned upon that is in std.

Generally not desired, as the long-term goal is to merge core, alloc, and std into a single crate, which would eliminate this problem and lead to redundant APIs.

1 Like

Why is ToOwned defined in liballoc? I see no reason not to move it to libcore instead.

1 Like

Probably so it can be implemented on str and [T] with the owned types being String and Vec<T>. liballoc couldn't implement ToOwned, an external trait, on [T], an external type.

3 Likes

Hmm, right. We do side-step the rules for impls a bit already (primitive types have inherent impls in both libcore and libstd), but perhaps not to this extent?

That's the same questions I asked myself...

I'm not quite sure what's the best way going forward. Any proposal where this should be implemented and how (extension trait, inherent method, etc.)?

Couldn't you define it with the definition of ToOwned? You can implement local traits for foreign types so I don't see the problem there.

ToOwned::Owned must implement Borrow<Self>, and there's no way for Option<T> to produce an &Option<&T>, which would be required for the Borrow implementation.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.