Trait bound in Service is not satisfied [Hyper]

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.

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);
1 Like

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

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?

1 Like

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.

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

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