Chrono parse_from_str() not part of a trait?


#1

Hi folks,

I’m trying to implement this generic fn:

fn to_datetime<T>(value: &str, fmt: &str) -> T {
    let converted = match T::parse_from_str(value, fmt) {
        Ok(v) => v,
        Err(e) => panic!("unable to convert string value {}", value),
    };
    converted
}

and use it like:

to_datetime::<NaiveDate>(..., ...)

but got hits error:

error: no associated item named `parse_from_str` found for type `T` in the current scope
  --> src/types/datetime.rs:25:27
   |
25 |     let converted = match T::parse_from_str(value, fmt) {
   |                           ^^^^^^^^^^^^^^^^^

error: aborting due to previous error

As far as I understand, this is because the

T

type is not bounds by a trait. I’m right ?


#2

Right. There is a FromStr impl for it, but of course you don’t get to specify the format (which I take is required for your usecase). Otherwise, from a cursory glance, it doesn’t look like there’s a trait providing parse_from_str there.


#3

@vitalyd

Thanks a lot, my understanding of the Rust language is progressing :wink:


#4

Just to frame it a bit more, what you wrote would work in a language that allows “duck typing” - in fact, C++ templates work like that (currently - without concepts). In Rust, however, the compiler/type system needs to know where that function is coming from; it doesn’t have to be the precise/concrete type, but a family of types (i.e. a trait) - sometimes called “typeclasses” in other languages.


#5

So this means that the compiler is verifying first and then apply monomorphization rather than the converse ?


#6

Yes, the compiler ensures that the generic function will work for any type which meets the specified bounds.


#7

@cuviper

Ok, that’s what I suspected. Thanks for your confirmation.