Sorry for bombarding with questions. Rust turned out not that intuitive to deal with futures.
I have the the following source code sample. The first arm of the match
in the call
function collects the body in non-blocking way (I hope) and maps the result to the response. The second constructs the result of the future directly. I understand why the compiler complains, but have no idea how to fix it. Could you please help me?
extern crate futures;
extern crate hyper;
extern crate tokio_core;
extern crate serde;
extern crate serde_json;
use futures::future::Future;
use hyper::server::{Http, Request, Response, Service};
use futures::Stream;
use std::panic;
use std::result;
use std::error;
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
struct AgentService;
impl AgentService {
fn get_body(&self, body: hyper::Body) -> Box<Future<Item=String, Error=<Self as hyper::client::Service>::Error>> {
let full_body = body.concat2()
.map(|chunk| {
let v = chunk.to_vec();
String::from_utf8_lossy(&v).to_string()
});
Box::new(full_body)
}
}
impl Service for AgentService {
// boilerplate hooking up hyper's server types
type Request = Request;
type Response = Response;
type Error = hyper::Error;
type Future = Box<Future<Item=Self::Response, Error=Self::Error>>;
fn call(&self, _req: Request) -> Box<Future<Item=Self::Response, Error=Self::Error>> {
//let result = panic::catch_unwind(|| {
println!("Received {:?}", _req);
let resp: Future<Item=Self::Response, Error=Self::Error> = match _req.path() {
"/avl" if _req.method() == &hyper::Method::Get => {
self.get_body(_req.body())
.map(|r| {
println!("{:?}", r);
let deserialized: Point = serde_json::from_str(&r).unwrap();
println!("deserialized: {:?}", deserialized);
let resp = Response::new().with_status(hyper::StatusCode::Created);
resp
})
}
_ => {
let resp = Response::new().with_status(hyper::StatusCode::NotFound);
futures::future::ok(resp)
}
};
Box::new(resp)
//});
//println!("Caught {:?}", result);
// match result {
// Ok(f) => {
// return f;
// }
// Err(e) => {
// return Box::new(futures::future::ok(Response::new().with_status(hyper::StatusCode::InternalServerError)));
// }
// }
}
}
pub fn run() {
let addr = "127.0.0.1:3000".parse().unwrap();
let server = Http::new().bind(&addr, || Ok(AgentService)).unwrap();
server.run().unwrap();
}
Compiler error:
error[E0308]: mismatched types
--> src\server.rs:49:21
|
49 | / self.get_body(_req.body())
50 | | .map(|r| {
51 | | println!("{:?}", r);
52 | | let deserialized: Point = serde_json::from_str(&r).unwrap();
... |
55 | | resp
56 | | })
| |__________________________^ expected trait futures::Future, found struct `futures::Map`
|
= note: expected type `futures::Future<Item=hyper::Response, Error=hyper::Error>`
found type `futures::Map<std::boxed::Box<futures::Future<Item=std::string::String, Error=hyper::Error>>, [closure@src\server.rs:50:30: 56:26]>`
How can I drop the Box of the inner result?