obsidian-rs / obsidian

Ergonomic async http framework for reliable and efficient web
MIT License
26 stars 4 forks source link

Can't use the header value from context in Response due to owndership #65

Open jk-gan opened 4 years ago

jk-gan commented 4 years ago

I want to use the header value from request and return in Response:

#[derive(Serialize)]
struct IndexResponse {
  message: String,
}

async fn index(ctx: Context) -> ContextResult {
  let hello = ctx.headers()
                .get("hello")
                .and_then(|v| v.to_str().ok())
                .unwrap_or_else(|| "world");

  ctx.build_json(IndexResponse { message: hello.to_owned() }).ok()
}

and I get the error:

❯ cargo run
   Compiling messages-obsidian v0.1.0 (/Users/jkgan/Developer/Rust/messages-obsidian)
error[E0505]: cannot move out of `ctx` because it is borrowed
  --> src/lib.rs:30:3
   |
25 |   let hello = ctx.headers()
   |               --- borrow of `ctx` occurs here
...
30 |   ctx.build_json(IndexResponse { message: hello.to_owned() }).ok()
   |   ^^^ move out of `ctx` occurs here       ----- borrow later used here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0505`.
error: could not compile `messages-obsidian`.

To learn more, run the command again with --verbose.
jk-gan commented 4 years ago

I fixed it by making the method doesn't own the ctx:

pub fn build(&self, res: impl Responder) -> ResponseBuilder {
    ResponseBuilder::new(res.respond_to())
}

and now I'm getting this error for closure:

error[E0515]: cannot return value referencing function parameter `ctx`
 --> examples/hello.rs:7:33
  |
7 |     app.get("/", |ctx: Context| async { ctx.build("Hello World").ok() });
  |                                 ^^^^^^^^---^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |                                 |       |
  |                                 |       `ctx` is borrowed here
  |                                 returns a value referencing data owned by the current function