I am trying to store a hyper::server::Server
as a member of my struct (struct MyApp
below). I can do this from, for example, my program's main()
function.
How can I do this in my struct's MyApp::new()
method? I think I need the concrete type for F
in MyApp<F>
. However, despite trying, I am unable to (correctly) specify a concrete type for this closure.
I can't figure out how to do this. I thought Box
ing the closure would work by allowing me to pass the closure as a concrete type, and indeed it does when I do this in main()
, but not MyApp::new()
. I am hoping there is a way to do this in stable rust, as I would really like to implement a structure which contains a hyper Server.
Here is my struct:
struct MyApp<F> {
hyper_server: Server<MyBoxedClosure<F>, hyper::Body>,
}
And here is the full code that works -- it sets the MyApp.hyper_server
field in 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 MyApp::new()
function and call that from the main()
instead, I can't figure out how to avoid a 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!");
}
The compiler error is this:
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]>`