What is the difference between the FromStr and TryFrom<String> traits?

Viewed 1337

When working with the Serde crate in Rust I tried to add a #[serde(try_from = String)] container attribute to a type that implements FromStr and thus can be parsed from string. Unfortunately this seems not enough for Serde, from the compiler error message it becomes obvious that I have to manually implement TryFrom<String>, too.

Why is TryFrom<String> not implemented automatically for all types that implement FromStr? And why is there a separate trait for fallible conversion from strings? What is the difference between these two traits?

2 Answers

FromStr was stable in Rust 1.0, TryFrom was stablized in Rust 1.34; it would be very hard to use the trait before it existed.

Why is TryFrom<String> not implemented automatically for all types that implement FromStr?

This would cause ambiguity with types that have already implemented both TryFrom and FromStr. An advanced form of specialization would be needed to allow this.

why is there a separate trait for fallible conversion from strings?

FromStr creates an owned value from a borrowed string slice (&str), so it's semantically different from taking ownership of a String. TryFrom<String> would allow you to reuse the memory allocated for the String.

The closer analog would be impl<'a> TryFrom<&'a str> for ..., but having the lifetime in the trait makes using it more complicated in "simple" cases of parsing a value out of a string.

See also:

TryFrom is a generic trait, which can be implemented for "any" type. From the documentation:

Simple and safe type conversions that may fail in a controlled way under some circumstances.

Type -> Type

It also provides an auto implementation of TryInto.

FromStr is used mostly to parse types, also as per the documentation:

FromStr's from_str method is often used implicitly, through str's parse method.

str -> Type

Implement it to be used by str::parse

Related