'Rust Hyper and Futures

I am getting started with Hyper on Rust. I have written a simple code(based on Hyper cannot find Server module ), and it seems to be nearly there, but running into few unexpected issues. Here is the minimized code snippet, should be easily reproducible. There 5 errors currently, marked with ISSUE comment:

use futures::{future, Future};
use hyper::service::service_fn;
use hyper::{Body, Error, Method, Request, Response, Server, StatusCode};
use lazy_static::lazy_static;
use log::{debug, info, trace};
use pretty_env_logger;
use rand;
use regex::Regex;
use slab::Slab;
use std::env;
use std::fmt;
use std::net::SocketAddr;
use std::sync::{Arc, Mutex};

lazy_static! {
    static ref INDEX_PATH: Regex = Regex::new("^/(index\\.html?)?$").unwrap();
    static ref USER_PATH: Regex = Regex::new("^/user/((?P<user_id>\\d+?)/?)?$").unwrap();
    static ref USERS_PATH: Regex = Regex::new("^/users/?$").unwrap();
}

fn mini() {
    pretty_env_logger::init();
    info!("Anatoly's Microservice 1.1");
    let addr: SocketAddr = env::var("ADDRESS")
        .unwrap_or_else(|_| "127.0.0.1:8080".into())
        .parse()
        .expect("can't parse ADDRESS variable");
    debug!("Trying to bind server to address: {}", addr);
    let builder = Server::bind(&addr);
    let udb = Arc::new(Mutex::new(Slab::new()));

    trace!("Creating service handler");
    let server = builder.serve(move || {
        // ISSUE on .serve
        let user_db = Arc::clone(&udb);

        service_fn(move |req| {
            trace!("Recieved Request: {:?}", req);
            microservice_handler(req, &user_db)
        })
    });
    info!("Used Addr: {}", server.local_addr());
    let server = server.map_err(drop); // ISSUE
    debug!("Run");
    hyper::rt::run(server); // ISSUUE cannot find function run in hyper rt
}

/// ISSUE associated type Item and Error not found for futures::Future
fn microservice_handler(
    req: Request<Body>,
    user_db: &UserDB,
) -> impl Future<Item = Response<Body>, Error = Error> {
    let response = {
        let method = req.method();
        let path = req.uri().path();
        let mut users = user_db.lock().unwrap();

        if INDEX_PATH.is_match(path) {
            if method == &Method::GET {
                let rand_byte = rand::random::<u8>();
                debug!("Generated value is: {}", rand_byte);
                Response::new(INDEX.replace("#RAND#", &*rand_byte.to_string()).into())
            } else {
                response_with_code(StatusCode::METHOD_NOT_ALLOWED)
            }
        }
        // --Long matching sequence here--
        else {
            response_with_code(StatusCode::NOT_FOUND)
        }
    };
    future::ok(response) //ISSUE cannot infer type E
}

fn response_with_code(status_code: StatusCode) -> Response<Body> {
    Response::builder()
        .status(status_code)
        .body(Body::empty())
        .unwrap()
}

// # is multiline string
const INDEX: &'static str = r#"
    <!doctype html>
    <html>
        <head>
            <title>Rust Microservices</title>
        </head>
        <body>
            <h3>Rust Microservices #RAND#</h3>
        </body>
    </html>
    "#;

type UserId = u64;
#[derive(Debug)]
struct UserData;
impl fmt::Display for UserData {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("{}")
    }
}
type UserDB = Arc<Mutex<Slab<UserData>>>;

The issues are:

  1. function run not found in module hyper::rt
  2. associated types Error and Item not found for futures::Future
  3. type annotations needed on future::ok
  4. no method named map_err found for struct Server
  5. the trait bound for<'a> [closure@src\main.rs:58:32: 64:6]: Service<&'a AddrStream> is not satisfied

My Cargo.toml:

slab = "0.4"
futures = "0.3.21"
hyper = {version = "0.14.17", features=["full"]}
lazy_static = "1.0"
regex = "1.0"
rand = "0.8.5"
log = "0.4"
pretty_env_logger = "0.4"
dotenv = "0.15"

How do I make my example compile? Any hints would be much appreciated!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source