Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

the trait rocket::request::FromFormValue<'_> is not implemented for models::chrono::NaiveDate #602

Closed
luisvonmuller opened this issue Apr 10, 2018 · 6 comments
Labels
question A question (converts to discussion)

Comments

@luisvonmuller
Copy link

luisvonmuller commented Apr 10, 2018

Setup

Versions

  • Rust:
    rustc 1.25.0-nightly

  • Rocket:
    0.3.8 (Apr 07, 2018)

  • Diesel:
    version = "1.1.0"

  • Database:
    PGsql 10.3

  • Operating System
    Windows 10 Fall creators update

Feature Flags

chrono = { version = "0.4", features = ["serde"] }

  • diesel:
    diesel = { version = "1.1.0", features = ["postgres", "chrono", "large-tables" ] }

Problem Description

I got a "NaiveDate" field at a diesel insertable struct that derives from rocket's request::FromForm and the trait bound models::chrono::NaiveDate: rocket::request::FromFormValue<'_> is not being satisfied.

#[derive(Insertable, Debug, FromForm)]
#[table_name="login"]
pub struct NewLogin {
pub username: String,
pub userpass: String,
pub creation_date: Option<self::chrono::NaiveDate>,
}

What is the expected output?

Successful compiling xD

What is the actual output?

error[E0277]: the trait bound models::chrono::NaiveDate: rocket::request::FromFormValue<'>is not satisfied --> examples\freedu\src\models.rs:116:29 | 116 | #[derive(Insertable, Debug, FromForm)] | ^^^^^^^^ the traitrocket::request::FromFormValue<'>is not implemented formodels::chrono::NaiveDate| = note: required because of the requirements on the impl ofrocket::request::FromFormValue<'_>forstd::option::Optionmodels::chrono::NaiveDate``

Steps to reproduce

  1. Create a struct with NaiveDate as a field type.
  2. Use "LanientForm" from rocket.rs to fill it.
  3. Add Derive(FromForm) to the struct;
  4. Bug.

Full code source:
https://github.com/luis-vmjr/freedu/blob/master/src/models.rs

Checklist

  • [X ] I have already looked over the issue tracker for similar issues.
@stammw
Copy link

stammw commented Apr 11, 2018

It looks like you're missing a few lines above the actual output you've pasted here.

Rocket doesn't know how to create Login structs from the post request data, to your controller's arguments:

#[post("/login", data = "<login>")]
fn login(mut cookies: Cookies, login: LenientForm<Login>) -> Flash<Redirect> {
                           //  ^^^^^^^^^^^^^^^^^^^^^^^^
                           //   Here, Rocket does not know how to parse post body to a Login struct,
                           //   because NaiveDate, inside it, does not implement FromFormValue

I think you just have to implement FromFormValue for the NaiveDate type yourself, like in the Field validation guide.

impl<'v> FromFormValue<'v> for NaiveDate {
    type Error = &'v RawStr;

    fn from_form_value(form_value: &'v RawStr) -> Result<NaiveDate, &'v RawStr> {
        // here, prase NaiveDate and return an instance of it
    }
}

See FromFormValue trait for more information about this.

@DJMcNab
Copy link
Contributor

DJMcNab commented Apr 11, 2018

But surely that leads to an orphaned impl, because he does not own NaiveDate or FromFormValue

I think that you could however create a wrapper, and use that in your Login; i.e:

struct NaiveDateForm(NaiveDate);

impl<'v> FromFormValue<'v> for NaiveDateForm {
    type Error = &'v RawStr;

    fn from_form_value(form_value: &'v RawStr) -> Result<NaiveDateForm, &'v RawStr> {
        // here, parse NaiveDate and return an instance of the wrapper
    }
}

impl Deref<NaiveDate> for NaiveDateForm{
    fn deref(self)->NaiveDate{
        self.0
    }
}

@SergioBenitez SergioBenitez added the question A question (converts to discussion) label Apr 13, 2018
@SergioBenitez
Copy link
Member

SergioBenitez commented Apr 13, 2018

We don't have built-in support for chrono, and chrono doesn't have built in support for Rocket. One of these would be required to allow this to work. That is, either chrono or rocket would need to implement FromFormValue for NaiveDate. We won't be doing that in Rocket's core, but perhaps you can ask chrono to do so under a rocket feature flag. I'd be amenable to doing this in contrib, but this isn't possible. Something like what I've proposed in rust-lang/rfcs#2315 (comment) would be required to do that, however.

In general, this is an issue caused by coherence, as @DJMcNab alludes to. The workaround is exactly as @DJMcNab writes, though the Deref impl above needs to be slightly tweaked to compile.

I think this answers the question. As such, I'm closing the issue out. Feel free to comment if you feel your question hasn't been answered.

@timando
Copy link
Contributor

timando commented Sep 16, 2021

Now that there's no longer a contrib crate, and Uuid has been added to core, does that change anything?

@NyxCode
Copy link

NyxCode commented Nov 8, 2021

I'm a bit suprised - Its super common in the rust ecosystem to gate an impl behind a feature.
It's done almost everywhere for serde, and also for chrono in a lot of places. Why is rocket different?

@perseoGI
Copy link

perseoGI commented Feb 23, 2023

Any updates on this on Rocket v5?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question A question (converts to discussion)
Projects
None yet
Development

No branches or pull requests

7 participants