2
votes

Better late than never and so I started re-learning Rust and decided to focus on actix and actix-web.

I have these codes running in actix-web 1.0 and it seems not to run in actix-web 3.0:

main.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
}

error: "no method named run found for opaque type impl std::future::Future in the current scope method not found in 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(),
        }))
}

error for index: the trait Factory<_, _, _> is not implemented for 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
    }
}

error: expected enum std::result::Result, found struct Server

checked the migration doc yet can't find what I'm looking for in relation to the errors listed.

Any help greatly appreciated...Thanks...

1

1 Answers

3
votes

Newer versions of actix-web now use the async-await syntax, which was made stable as of Rust 1.39. You have to make your handlers async:

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

Creating an HttpServer is now an async operation:

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

And you can use the main macro to use async/await in your main function:

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