Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I express a trait bound on a type parameter for another generic type's trait bound?

I'm trying to improve some existing code I to make it more generic, by adding a type variable in place of a concrete type.

The original code looked like this:

fn parse_row(text: String) -> Result<Vec<u32>, String> {
    text.split(" ")
        .map(|s| s.to_owned()
            .parse::<u32>()
            .map_err(|e| e.to_string())
        )
        .collect()
}

And here is the generic version:

fn parse_row<T>(text: String) -> Result<Vec<T>, String>
where
    T: Copy + Debug + FromStr + Display,
{
    text.split(" ")
        .map(|s| s.to_owned()
            .parse::<T>()
            .map_err(|e| e.to_string())
        )
        .collect()
}

The error I get is:

error[E0599]: no method named `to_string` found for type `<T as std::str::FromStr>::Err` in the current scope
 --> src/main.rs:7:28
  |
7 |             .map_err(|e| e.to_string())
  |                            ^^^^^^^^^
  |
  = note: the method `to_string` exists but the following trait bounds were not satisfied:
          `<T as std::str::FromStr>::Err : std::string::ToString`

<T as core::str::FromStr>::Err is referring to the type parameter associated with T's FromStr implementation, but how can I express that this type — that I can't actually know — has the Display trait?

like image 499
Peter Hall Avatar asked Nov 28 '15 21:11

Peter Hall


1 Answers

This was confusing initially because I didn't understand which Err it was referring to - and thought it was the error type parameter for Result. Once I figured out that FromStr has its own Err type parameter, I just had to work out how to express that constraint. And here it is:

fn parse_row<T>(text: String) -> Result<Vec<T>, String>
where
    T: Copy + Debug + FromStr,
    T::Err: Display,
{
    text.split(" ")
        .map(|s| s.to_owned()
            .parse::<T>()
            .map_err(|e| e.to_string())
        )
        .collect()
}
like image 84
Peter Hall Avatar answered Sep 28 '22 12:09

Peter Hall