The trait `for<'de> serde::de::Deserialize<'de>` is not implemented for `&std::collections::HashMap<std::string::String, std::string::String>`

Hi folks,

I've dug and researched and read but I just don't understand what is going wrong here.

I'm afraid I just can't make sense of how to resolve this would someone mind helping me out please?

Here is the error:

ubuntu@ubuntu:~/$ cargo run
   Compiling warp-postgres-example v0.1.0 (/home/ubuntu/)
error[E0277]: the trait bound `for<'de> &std::collections::HashMap<std::string::String, std::string::String>: serde::de::Deserialize<'de>` is not satisfied
   --> src/
18  |             .and(warp::body::form())
    |                  ^^^^^^^^^^^^^^^^ the trait `for<'de> serde::de::Deserialize<'de>` is not implemented for `&std::collections::HashMap<std::string::String, std::string::String>`
   ::: /home/ubuntu/.cargo/registry/src/
208 | pub fn form<T: DeserializeOwned + Send>() -> impl Filter<Extract = (T,), Error = Rejection> + Copy {
    |                ---------------- required by this bound in `warp::body::form`
    = help: the following implementations were found:
              <std::collections::HashMap<K, V, S> as serde::de::Deserialize<'de>>
    = note: required because of the requirements on the impl of `serde::de::DeserializeOwned` for `&std::collections::HashMap<std::string::String, std::string::String>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `warp-postgres-example`.

To learn more, run the command again with --verbose.

Here is the code:

use warp::{self, http, Filter, Rejection, Reply};
use std::collections::HashMap;

type Result<T> = std::result::Result<T, Rejection>;

pub async fn test_route_form_handler(
    form: &HashMap<String, String>,
) -> Result<impl Reply> {
    let json = warp::reply::json(&vec![1]);
    Ok(warp::reply::with_status(json, http::StatusCode::UNAUTHORIZED))

async fn main() {
    let test_route_form =

    let routes = test_route_form

    warp::serve(routes).run(([127, 0, 0, 1], 8001)).await;

And the Cargo.toml

name = "foo"
version = "0.1.0"
authors = ["example <>"]
edition = "2018"

tokio = { version = "0.2", features = ["macros", "rt-threaded"] }
warp = "0.2"
mobc-postgres = { version = "0.5", features = ["with-chrono-0_4"] }
mobc = "0.5"
serde = {version = "1.0", features = ["derive"] }
serde_derive = "1.0"
serde_json = "1.0"
thiserror = "1.0"
chrono = { version = "0.4", features = ["serde"] }
log = "0.4.0"
env_logger = "0.7.1"
pretty_env_logger = "0.4.0"

debug = 0

I believe the error is due to the fact that there is no implementation to deserialise the form into a &HashMap, or in other words a reference to a hash map. That makes some sense, as if it is just a plain reference, what would own the data that is being referenced?

If that’s right, then I’d expect changing the deserialisation target to an owned HashMap would fix it:

pub async fn test_route_form_handler(
    form: HashMap<String, String>,
) -> Result<impl Reply>

@douglas thankyou. It seems I have a long way to go to grasp what's going on.

No problem, hopefully that suggestion worked. It took me a little while to get used to the idea of functions having inferred return types, Rust is the first language I’ve seriously used that supports them, though I know quite a few others do too.

I think the key to understanding the error you posed is this bit:

the trait bound `&Foo: Bar` is not satisfied

That means the type &Foo would need to implement the trait Bar. The suggestions at the end then makes more sense:

the following implementations were found:
          <Foo as Bar>

Since there is an implementation of Bar for Foo, even if there isn’t one for &Foo.

1 Like