Как мне написать обработчики HTTP, используя гипер? - PullRequest
0 голосов
/ 28 марта 2020

Я пытаюсь написать простой сервер REST, используя hyper :


pub struct APIServer{
    port: u16,
    memtable: RwLock<Memtable>
}

#[derive(Deserialize, Debug)]
pub struct KeyValuePair {
    key : String,
    value : String,
}

impl APIServer {
    pub fn new(port: u16, path: String) -> Result<APIServer, io::Error> {
        let path = Path::new(&path);
        let memtable = Memtable::new(path)?;

        let server = APIServer {
            port: port,
            memtable: RwLock::<Memtable>::from(memtable),
        };
        Ok(server)
    }

    pub async fn run(&self) {
        let addr = SocketAddr::from(([127, 0, 0, 1], self.port));

        println!("Listening on {}", addr);     

        let serve_future = Server::bind(&addr).serve(make_service_fn(|_conn| {
            async {
                {
                    Ok::<_, hyper::Error>(service_fn(router))
                }
            }
        }));

        // Wait for the server to complete serving or exit with an error.
        // If an error occurred, print it to stderr.
        if let Err(e) = serve_future.await {
            eprintln!("server error: {}", e);
        }
    }


    // Router routes requests to approporiate http handlers.
    fn router(&self) -> Box<dyn Fn(Request<Body>) -> Result<Response<Body>, hyper::Error>> {
        return Box::new(|req| async move {
            let mut response = Response::new(Body::empty());

            match (req.method(), req.uri().path()) {
                (&Method::GET, "/{key}") => {
                    handlers::get_value(req)
                }
                (&Method::POST, "/") => {
                    handlers::write_key_value_pair(req).await
                }
                _ => {
                    *response.status_mut() = StatusCode::NOT_FOUND;
                    Ok(response)
                }
            }
        });
    }
}

Проблема заключается в том, что я хотел бы использовать поля APIServers внутри http обработчики (и сам router) - т.е. использовать их как «service_fn» ( 1 , 2 ), таким образом, их подпись будет fn foo_handler(Request<Body>) -> Result<Response<Body>, hyper::Error:error> - для решения этой проблемы Я заставил маршрутизатор вернуть закрытие, которое содержит указанную выше подпись.

Но теперь я получаю следующую ошибку:


expected enum `std::result::Result`, found opaque type

note:     expected enum `std::result::Result<http::response::Response<hyper::body::body::Body>, hyper::error::Error>`
      found opaque type `impl futures::Future`rustc(E0308)
server.rs(58, 31): expected enum `std::result::Result`, found opaque type

Короче, как я могу использовать маршрутизатор и обработчики как методы, чтобы я мог передать им определенные закрытые поля? без нарушения договора.

...