2

I try write my first rust web demo with actix-web. I copied the example in actix-web welcome web page and changed it as below:

use actix_web::{get, App, HttpRequest, HttpServer, Responder};
use std::io::Result;

#[get("/{name}")]
async fn greet(req: HttpRequest) -> impl Responder {
    let name = req.match_info().get("name").unwrap_or("World");
    format!("Hello {}!", &name)
}

#[get("/")]
async fn greet2(req: HttpRequest) -> impl Responder {
    greet(req)
}

#[actix_web::main]
async fn main() -> Result<()> {
    HttpServer::new(|| App::new().service(greet).service(greet2))
        .bind(("127.0.0.1", 8080))?
        .run()
        .await
}

I'm trying to call async function "greet" in another async function "greet2" and got compile error:

   Compiling rust-http-demo v0.1.0 (/Users/xxx/codes/practice/rust-http-demo)
error[E0618]: expected function, found `greet`
  --> src/main.rs:12:5
   |
4  | #[get("/{name}")]
   | ----------------- `greet` defined here
...
12 |     greet(req)
   |     ^^^^^-----
   |     |
   |     call expression requires function

For more information about this error, try `rustc --explain E0618`.
error: could not compile `rust-http-demo` due to previous error

I realized async function cannot be called as normal function, but the compiler's message puzzles me. What does it mean and how can I fix it?

2
  • 1
    greet(req).await, you need to await the future in order to get the Responder Commented Jan 8, 2022 at 12:04
  • 1
    Actually, that may be not enough, since get is a macro that is modifying the function itself. I don't know if you could actually use it as a plain function anymore. Commented Jan 8, 2022 at 12:06

1 Answer 1

4

An async function returns a Future, you need to await the future to get the result. In your case the Responder:

#[get("/")]
async fn greet2(req: HttpRequest) -> impl Responder {
    greet(req).await
}

But this may not even be enough. get is a macro that modifies your function definition. Look source.

You can not call it itself. Would be better to take the implementation outside of the macro wrapped call:

async fn greet_prime(req: HttpRequest) -> impl Responder {
    let name = req.match_info().get("name").unwrap_or("World");
    format!("Hello {}!", &name)
}

#[get("/{name}")]
async fn greet(req: HttpRequest) -> impl Responder {
    greet_prime(req).await
}

#[get("/")]
async fn greet2(req: HttpRequest) -> impl Responder {
    greet_prime(req).await
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.