The Rust book explains following:
The From trait allows for a type to define how to create itself from another type, hence providing a very simple mechanism for converting between several types.
Sounds simple enough. Lets try as simple example as possible:
use std::str::FromStr; struct MyStructure {} // auto accepted suggestion from language server. impl FromStr for MyStructure { type Err = (); // I've added this fn from_str(_s: &str) -> Result<Self, Self::Err> { Ok(Self {}) // I've added this } } fn main() { const INPUT: &str = "test"; let _tmp: MyStructure = MyStructure::from(INPUT); } Compiling test_range_2 v0.1.0 (/home/pavel/Repositories/test_range_2) error[E0308]: mismatched types --> src/main.rs:15:47 | 15 | let _tmp: MyStructure = MyStructure::from(INPUT); | ----------------- ^^^^^ expected struct `MyStructure`, found `&str` | | | arguments to this function are incorrect | note: associated function defined here --> /home/pavel/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/convert/mod.rs:374:8 | 374 | fn from(_: T) -> Self; | ^^^^ For more information about this error, try `rustc --explain E0308`. error: could not compile `test_range_2` due to previous error So I expected this behavior:
let target: TARGET_TYPE = TARGET_TYPE::from::<SOURCE_TYPE>(input_var: SOURCE_TYPE); Compared to the example in the rust book:
let num = Number::from(30); It seems to me like a reasonable assumption.
However, reading the error message: "expected struct MyStructure, found &str". Does that mean that syntax is like this?
let target: TARGET_TYPE = TARGET_TYPE::from::<TARGET_TYPE>(input_var: TARGET_TYPE); If, that's true, then code in the rust book should also fail with the error "expected Number, found i32", but it doesn't.
I expected my solution to work because I've implemented the trait FromStr, and I'm trying to create object from &str (see the "from" and "str"?). Which is also the type that was autocompleted by language server after I've typed impl FromStr for MyStructure. What am I missing? I want to impl FromStr for all my types but that compiler is not making it easy.
Solution
use std::str::FromStr; struct MyStructure {} impl FromStr for MyStructure { type Err = (); fn from_str(_s: &str) -> Result<Self, Self::Err> { Ok(Self {}) } } impl From<&str> for MyStructure { fn from(_: &str) -> Self { Self {} } } fn main() { const INPUT: &str = "test"; let _tmp0 = MyStructure::from_str(INPUT); let _tmp1 = MyStructure::from(INPUT); } I implemented trait FromStr but was referring to trait From<&str>. Since there is a trait in standard lib that looks like this:
trait From<T> -> T compiler tried to use that in stead.
core::convert::From.FromStris a different trait with different methods and expectations. They are not linked in such a way that would allow you to doMyStructure::from(INPUT).From, why are you usingFromStr?