迁移到 actix-web 3.0 时出错

问题描述

迟到总比不到好,所以我开始重新学习 Rust 并决定专注于 actix 和 actix-web。

我有这些代码在 actix-web 1.0 中运行,但它似乎不能在 actix-web 3.0 中运行:

ma​​in.rs

 use messages_actix::MessageApp;


 fn main() -> std::io::Result<()> {
    std::env::set_var("RUST_LOG","actix_web=info");
    env_logger::init();
    let app = MessageApp::new(8081);
    app.run() // error here
}

错误:“在 run 中未找到的当前范围方法中,没有为不透明类型 impl std::future::Future 找到名为 impl std::future::Future方法

lib.rs

#[macro_use]
extern crate actix_web;

use actix_web::{middleware,web,App,HttpRequest,HttpServer,Result};
use serde::Serialize;

pub struct MessageApp {
    pub port: u16,}

#[derive(Serialize)]
pub struct IndexResponse{
    pub message: String,}

#[get("/")]
pub fn index(req: HttpRequest) -> Result<web::Json<IndexResponse>> {  // error here
    let hello = req
        .headers()
        .get("hello")
        .and_then(|v| v.to_str().ok())
        .unwrap_or_else(|| "world");
    
        Ok(web::Json(IndexResponse {
            message: hello.to_owned(),}))
}

索引错误:特征 Factory<_,_,_> 没有为 fn(HttpRequest) -> std::result::Result<Json<IndexResponse>,actix_web::Error> {<index as HttpServiceFactory>::register::index} 实现

impl MessageApp {
    pub fn new(port: u16) -> Self {
        MessageApp{ port }
    }

    pub fn run(&self) -> std::io::Result<()> {
        println!("Starting HTTP server at 127.0.0.1:{}",self.port);
        HttpServer::new(move || {
            App::new()
            .wrap(middleware::Logger::default())
            .service(index)
        })
        .bind(("127.0.0.1",self.port))?
        .workers(8)
        .run() //error here
    }
}

错误:预期枚举 std::result::Result,找到结构 Server

检查了迁移 doc 但找不到与列出的错误相关的内容

非常感谢任何帮助...谢谢...

解决方法

较新版本的 actix-web 现在使用 async-await 语法,它在 Rust 1.39 中变得稳定。你必须让你的处理程序async

#[get("/")]
pub async fn index(req: HttpRequest) -> Result<web::Json<IndexResponse>> {
    // ...
}

创建 HttpServer 现在是一个 async 操作:

impl MessageApp {
    pub fn run(&self) -> std::io::Result<()>
        HttpServer::new(...)
          .run()
          .await
    }
}

并且您可以使用 main 宏在主函数中使用 async/await:

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let app = MessageApp::new(8081);
    app.run().await
}