Trait bound in Service is not satisfied [Hyper]


#1

Hello,
I can not understand why I got a not satisfaction in Service.

extern crate futures;
extern crate hyper;
extern crate tokio_core;

struct ResponseExamples(tokio_core::reactor::Handle);

pub type ResponseStream = Box<futures::Stream<Item = hyper::Chunk, Error = hyper::Error>>;

impl hyper::server::Service for ResponseExamples {
    type Request = hyper::Request;
    type Response = hyper::Response<ResponseStream>;
    type Error = hyper::Error;
    type Future = Box<futures::Future<Item = Self::Response, Error = Self::Error>>;
    fn call(&self, req: hyper::Request) -> Self::Future {
        let mut response = hyper::Response::new();

        match (req.method(), req.path()) {
            (&hyper::Method::Get, "/") => {
                response.set_body("Try POSTing data to /echo");
            }
            (&hyper::Method::Post, "/echo") => {
                // we'll be back
            }
            _ => {
                response.set_status(hyper::StatusCode::NotFound);
            }
        };

        Box::new(futures::future::ok(response))
    }
}

fn main() {
    let addr = "127.0.0.1:1337".parse().unwrap();
    let mut core = tokio_core::reactor::Core::new().unwrap();
    let server_handle = core.handle();
    let client_handle = core.handle();

    let serve = hyper::server::Http::new()
        .serve_addr_handle(&addr, &server_handle, move || {
            Ok(ResponseExamples(client_handle.clone()))
        })
        .unwrap();
}

And it’s error :

error[E0277]: the trait bound `futures::Future<Error=hyper::Error, Item=hyper::Response<std::boxed::Box<futures::Stream<Item=hyper::Chunk, Error=hyper::Error> + 'static>>> + 'static: futures::future::Future` is not satisfied
 --> src/main.rs:9:6
  |
9 | impl hyper::server::Service for ResponseExamples {
  |      ^^^^^^^^^^^^^^^^^^^^^^ the trait `futures::future::Future` is not implemented for `futures::Future<Error=hyper::Error, Item=hyper::Response<std::boxed::Box<futures::Stream<Item=hyper::Chunk, Error=hyper::Error> + 'static>>> + 'static`
  |
  = note: required because of the requirements on the impl of `futures::future::Future` for `std::boxed::Box<futures::Future<Error=hyper::Error, Item=hyper::Response<std::boxed::Box<futures::Stream<Item=hyper::Chunk, Error=hyper::Error> + 'static>>> + 'static>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
error: Could not compile `tests`.

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

Could please someone tell me what is solution.


#2

I think the issue is actually with the

response.set_body("Try POSTing data to /echo");

line. This doesn’t match the type of body the response expects, which is the ResponseStream type alias you defined. Instead, you probably want the following:

let chunk = hyper::Chunk::from("Try POSTing data to /echo");
response.set_body(Box::new(futures::stream::once(Ok(chunk))) as ResponseStream);

#3

@vitalyd : thank you for your response.
As you say I changed the type of body, unfortunately, the problem still exists.


#4

What version of futures are you using? Also, can you paste the full code you have now with the changes applied and the full error?


#5

Cargo.toml :

[dependencies]
hyper = "0.11"
tokio-core = "0.1"
futures = "0.2"

main.rs :

extern crate futures;
extern crate hyper;
extern crate tokio_core;

struct ResponseExamples(tokio_core::reactor::Handle);

pub type ResponseStream = Box<futures::Stream<Item = hyper::Chunk, Error = hyper::Error>>;

impl hyper::server::Service for ResponseExamples {
    type Request = hyper::Request;
    type Response = hyper::Response<ResponseStream>;
    type Error = hyper::Error;
    type Future = Box<futures::Future<Item = Self::Response, Error = Self::Error>>;
    fn call(&self, req: hyper::Request) -> Self::Future {
        let mut response = hyper::Response::new();

        match (req.method(), req.path()) {
            (&hyper::Method::Get, "/") => {
                let chunk = hyper::Chunk::from("Try POSTing data to /echo");
                response.set_body(Box::new(futures::stream::once(Ok(chunk))) as ResponseStream);
            }
            (&hyper::Method::Post, "/echo") => {
                // we'll be back
            }
            _ => {
                response.set_status(hyper::StatusCode::NotFound);
            }
        };

        Box::new(futures::future::ok(response))
    }
}

fn main() {
    let addr = "127.0.0.1:1337".parse().unwrap();
    let mut core = tokio_core::reactor::Core::new().unwrap();
    let server_handle = core.handle();
    let client_handle = core.handle();

    let serve = hyper::server::Http::new()
        .serve_addr_handle(&addr, &server_handle, move || {
            Ok(ResponseExamples(client_handle.clone()))
        })
        .unwrap();
}

Error :

   Compiling test1 v0.1.0 (file:///Users/test1/Documents/Projects/test1)
error[E0277]: the trait bound `futures::Future<Error=hyper::Error, Item=hyper::Response<std::boxed::Box<futures::Stream<Item=hyper::Chunk, Error=hyper::Error> + 'static>>> + 'static: futures::future::Future` is not satisfied
 --> src/main.rs:9:6
  |
9 | impl hyper::server::Service for ResponseExamples {
  |      ^^^^^^^^^^^^^^^^^^^^^^ the trait `futures::future::Future` is not implemented for `futures::Future<Error=hyper::Error, Item=hyper::Response<std::boxed::Box<futures::Stream<Item=hyper::Chunk, Error=hyper::Error> + 'static>>> + 'static`
  |
  = note: required because of the requirements on the impl of `futures::future::Future` for `std::boxed::Box<futures::Future<Error=hyper::Error, Item=hyper::Response<std::boxed::Box<futures::Stream<Item=hyper::Chunk, Error=hyper::Error> + 'static>>> + 'static>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: Could not compile `test1`.

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

#6

Use futures 0.1 - I don’t think 0.2 is compatible with tokio 0.1 (ie tokio-core).


#7

That’s work.
Thank you so much :hibiscus: :bouquet: .