methodsrustroutesclosuresrust-warp

Root path example with warp?


This is the rust warp example for newbies to get started. It's supposed to be "super easy" but it currently makes me feel super stupid.

use warp::Filter;

#[tokio::main]
async fn main() {
    // GET /hello/warp => 200 OK with body "Hello, warp!"
    let hello = warp::path!("hello" / String)
        .map(|name| format!("Hello, {}!", name));

    warp::serve(hello)
        .run(([127, 0, 0, 1], 3030))
        .await;
}

I'd like to run this on the root path, defined like this:

let hello = warp::path!("" /).map(|| "Hello!");

But the macro doesn't take an empty path name. I get the error:

no rules expected the token `start`

I guess "super easy" means different things to different people.

Addendum:

So, I tried the solution mentioned by Ivan C (comment below) from here It doesn't work either. Applying that solution

let hello = warp::path::end().map(|name| format!("Hello"));

Leads in turn to this error message:

   [rustc E0599] [E] no method named `map` found for opaque type `impl warp::Filter+std::marker::Copy` in the current scope
method not found in `impl warp::Filter+std::marker::Copy`
note: the method `map` exists but the following trait bounds were not
satisfied: `impl warp::Filter+std::marker::Copy: std::iter::Iterator`

Seems like routing with warp paths only works if one does not need a root route, which is simply a show stopper.


Solution

  • This does not compile:

    let hello = warp::path::end()
        .map(|name| format!("Hello"));
    

    Because where would the name argument in your closure be coming from if you're no longer dynamically matching on any part of the route path anymore? If you remove the unused name argument, and the format! is also unnecessary, then it works:

    use warp::Filter;
    
    #[tokio::main]
    async fn main() {
        let hello = warp::path::end()
            .map(|| "Hello");
    
        warp::serve(hello)
            .run(([127, 0, 0, 1], 3030))
            .await;
    }
    

    Visiting http://127.0.0.1:3030 now produces Hello.