我开始在 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>>>;
问题是:
- 在模块中找不到函数运行
hyper::rt
- 相关类型 Error 和 Item not found
futures::Future
- 类型注释需要
future::ok
- 没有为 struct Server 找到名为 map_err 的方法
- 特质界
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"
如何编译我的示例?任何提示将不胜感激!