1
votes

I'm trying to parse a request body to a strongly typed object using serde_json:

#[macro_use]
extern crate serde_derive; // 1.0.70
extern crate futures; // 0.1.23
extern crate hyper;   // 0.12.7
extern crate serde_json; // 1.0.24

use futures::{Future, Stream};
use hyper::{Body, Request};

struct AppError;

#[derive(Serialize, Deserialize)]
struct BasicLoginRequest {
    email: String,
    password: String,
}

impl BasicLoginRequest {
    fn from(req: Request<Body>) -> Result<BasicLoginRequest, AppError> {
        let body = req
            .body()
            .fold(Vec::new(), |mut v, chunk| {
                v.extend(&chunk[..]);
                futures::future::ok::<_, hyper::Error>(v)
            }).and_then(move |chunks| {
                let p: BasicLoginRequest = serde_json::from_slice(&chunks).unwrap();
                futures::future::ok(p)
            }).wait();

        Ok(body.unwrap())
    }
}

fn main() {}

The error I get is:

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:20:20
   |
20 |           let body = req
   |  ____________________^
21 | |             .body()
   | |___________________^ cannot move out of borrowed content

From Cannot move out of borrowed content when unwrapping I know that this error happens when unwrapping because a value is needed but a reference was supplied. The error points at req.body(); it seems like req.body() returns a reference, rather than a value...

The code that tries to handle the body is based on an excerpt copy-pasted from Extracting body from Hyper request as a string

How do I make this work?

1

1 Answers

4
votes

I highly recommend reading (at the very least skimming) the documentation for types you use, especially when you are having trouble using them.

For example, Request::body is defined as:

pub fn body(&self) -> &T

The very next two methods are

You want to use into_body.

I also use Control-F in my web browser to search for -> T once I know that the non-working method returns -> &T.