Search code examples
rustrust-rocket

How to create Response from String?(Rust-Rocket)


I tried to implement the Responder trait for "MyConfig" struct. But I don't know how to create Response (including the body whose type is String) which can be return from function.

I tried this code.

#[derive(Debug)]
struct MyConfig {
    body: String,
}

impl<'r> Responder<'r> for MyConfig {
    fn respond_to(self, _req: &Request) -> response::Result<'r> {
        let body: String = self.body.clone();
        Response::build()
            .status(Status::Ok)
            // .raw_header("Access-Control-Allow-Origin", "*")
            .sized_body(Cursor::new(body.as_str()))
            .ok()
    }
}

This can't compile, and shows this error.

error[E0515]: cannot return value referencing local variable `body`
  --> src/main.rs:53:9
   |
53 | /         Response::build()
54 | |             .status(Status::Ok)
55 | |             // .raw_header("Access-Control-Allow-Origin", "*")
56 | |             .sized_body(Cursor::new(body.as_str()))
   | |                                     ---- `body` is borrowed here
57 | |             .ok()
   | |_________________^ returns a value referencing data owned by the current function

Solution

  • body is a local variable and body.as_str() is a reference to that local variable. The reference doesn't live long enough to be included as part of the Result returned from the function.

    Since you don't need bodyfor anything after using it in Cursor::new(), could you pass it directly rather than as a reference:

    .sized_body(Cursor::new(body))
    

    ETA: I found this example:

    Response::build()
        .sized_body(Cursor::new(format!("{}:{}", self.name, self.age)))
    

    (from https://api.rocket.rs/v0.4/rocket/response/trait.Responder.html)

    They're calling Cursor::new() with a String rather than a reference, so Cursor::new(body) should work.

    Come to think of it, though, since you're passing self directly into the function rather than as a reference, maybe you could skip creating body entirely and just say:

    .sized_body(Cursor::new(self.body))