0

我开始在 Rust 上使用 Hyper。我写了一个简单的代码(基于Hyper cannot find Server module),它似乎就在那里,但遇到了一些意想不到的问题。这是最小化的代码片段,应该很容易重现。目前有 5 个错误,标有 ISSUE 注释:

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>>>;

问题是:

  1. 在模块中找不到函数运行hyper::rt
  2. 相关类型 Error 和 Item not foundfutures::Future
  3. 类型注释需要future::ok
  4. 没有为 struct Server 找到名为 map_err 的方法
  5. 特质界for<'a> [closure@src\main.rs:58:32: 64:6]: Service<&'a AddrStream> is not satisfied

我的货物.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"

如何编译我的示例?任何提示将不胜感激!

4

0 回答 0