How to store hyper :: server :: Server with default handler as struct field in constructor?

I am trying to save hyper::server::Server

as a member of my structure ( struct MyApp

below). I can do this, for example, from my program main()

.

How do I do this in my struct method MyApp::new()

? I think I need a specific type for F

in MyApp<F>

. However, despite trying, I cannot (correctly) specify the specific type for this closure.

I cannot figure out how to do this. I thought the Box

closure would work, allowing me to skip the closure as a concrete type, and indeed when I do it in main()

, but not MyApp::new()

. I hope there is a way to do this in stable rust, as I would really like to implement a framework containing a hyperserver.

Here is my structure:

struct MyApp<F> {
    hyper_server: Server<MyBoxedClosure<F>, hyper::Body>,
}

      

And here's the complete code that works - it sets the field MyApp.hyper_server

to main()

:

extern crate hyper;
extern crate futures;
use hyper::Error;
use hyper::server::{Http, Server, NewService, Service, Request, Response};
use hyper::header::ContentLength;

pub struct HelloWorld;

const PHRASE: &'static str = "Hello, World!";

impl Service for HelloWorld {
    type Request = Request;
    type Response = Response;
    type Error = hyper::Error;
    type Future = futures::future::FutureResult<Self::Response, Self::Error>;

    fn call(&self, _req: Request) -> Self::Future {
        futures::future::ok(
            Response::new()
                .with_header(ContentLength(PHRASE.len() as u64))
                .with_body(PHRASE),
        )
    }
}

pub struct MyBoxedClosure<F> {
    value: Box<F>,
}

impl<F> NewService for MyBoxedClosure<F>
where
    F: Fn() -> std::result::Result<HelloWorld, std::io::Error>,
{
    type Request = Request;
    type Response = Response;
    type Error = Error;
    type Instance = HelloWorld;

    fn new_service(&self) -> std::result::Result<Self::Instance, std::io::Error> {
        self.value.new_service()
    }
}

struct MyApp<F> {
    hyper_server: Server<MyBoxedClosure<F>, hyper::Body>,
}

fn main() {
    let mbc = MyBoxedClosure { value: Box::new(|| Ok(HelloWorld)) };
    let addr = "127.0.0.1:3000".parse().unwrap();
    let hyper_server = Http::new().bind(&addr, mbc).unwrap();
    let my_app = MyApp { hyper_server: hyper_server };

    println!("Hello, world!");
}

      

If I create a function MyApp::new()

and call it from main()

, I cannot figure out how to avoid compiler error.

impl<F> MyApp<F>
where
    F: Fn() -> std::result::Result<HelloWorld, std::io::Error> + Send + Sync,
{
    fn new() -> MyApp<F> {
        let mbc = MyBoxedClosure { value: Box::new(|| Ok(HelloWorld)) };
        let addr = "127.0.0.1:3000".parse().unwrap();
        let hyper_server = Http::new().bind(&addr, mbc).unwrap();
        MyApp { hyper_server: hyper_server }
    }
}

fn main() {
    let _my_app = MyApp::new();
    println!("Hello, world!");
}

      

Compiler error:

error[E0308]: mismatched types
  --> src/main.rs:56:9
   |
56 |         MyApp { hyper_server: hyper_server }
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found closure
   |
   = note: expected type `MyApp<F>`
              found type `MyApp<[closure@src/main.rs:53:52: 53:69]>`

      

+3


source to share





All Articles