Implement traits for &str and Option String - Option<String>: From<&str> and Option<String>: From<Option<&str>>

Currently in Rust, you can convert the following types:

  • &str -> String
  • String -> Option<String>

with the From<T> trait by calling .into().

Given that Option<String> implements From<&str>, it would be nice if you could also go from &str into Option<String> and Option<&str> into Option<String> with the following implementations:

impl From<&str> for Option<String> {
    fn from(s: &str) -> Option<String> {
        Some(s.to_owned())
    }
}

impl From<Option<&str>> for Option<String> {
    fn from(s: Option<&str>) -> Option<String> {
        s.map(Owned::to_owned)
    }
}

The following code would then compile:

// Already works in stable rust
let my_string = String::from("hello");
let my_option_string: Option<String> = my_string.into();

// My proposal
let a: &str = "hey";
let b: Option<String> = a.into();

let b: Option<&str> = Some("hey");
let c: Option<String> = b.into();
2 Likes

What's wrong with writing Some(a.into()) or String::from(a).into()?

That works, but when working with traits it has issues. Especially in my case with writing a macro.

For example, you have a generic which is Into<Option<String>>, it should work with &str, and Option<&str>.

If you need a more specific or larger sets of types than those implementing Into<Option<String>>, you can always use your own trait.

Regarding your “case with writing a macro”, I can't find anything about that in your post, maybe you'd like to provide more context.


The type &str also supports Into<Box<str>> and Into<Rc<&str>> and Into<Vec<u8>> and a few more. Adding Into<Option<…>> variants of all of those, too, would quickly become a surprisingly large number of new impls; not doing it may seem inconsistent.

These are all no definite arguments against the trait implementation(s) you're proposing, just things to consider.

1 Like

Those are valid points.

Looking at the documentation for the From trait, it seems like there are 5 other types which might also make sense to be implemented with the Option variant. These types are: char, Box<str>, &String, &mut str, Cow<'a, str>, and the &str as already mentioned.

I agree it might be inconsistent to not implement these types wrapped in an Option, but 12 new implementations doesn't seem like a whole lot, provided the fact that existing code wouldn't break.

The new implementations would be:

  • impl From<&str> for Option<String>
  • impl From<Option<&str>> for Option<String>
  • impl From<char> for Option<String>
  • impl From<Option<char>> for Option<String>
  • impl From<Box<str>> for Option<String>
  • impl From<Option<Box<str>>> for Option<String>
  • impl From<&String> for Option<String>
  • impl From<Option<&String>> for Option<String>
  • impl From<&mut str> for Option<String>
  • impl From<Option<&mut str>> for Option<String>
  • impl<'a> From<Cow<'a, str>> for Option<String>
  • impl<'a> From<Option<Cow<'a, str>>> for Option<String>