'Using Axum, creating a router I get error "use of moved value: `router`" but why?

I'm coming from Go. I'm new to Rust.

I'm using axum and this code to create a server:

use axum::{response::Html, routing::get, Router};
use std::net::SocketAddr;

#[tokio::main]
async fn main() {
    let router = Router::new();

    router.route("/", get(handler));

    if true { // I need to check something here
      router.route("/other", get(handler));
    }

    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    println!("listening on {}", addr);
    axum::Server::bind(&addr)
        .serve(router.into_make_service())
        .await
        .unwrap();
}

async fn handler() -> Html<&'static str> {
    Html("<h1>Hello, World!</h1>")
}

but it gives this error:

33 |     let router = Router::new();
   |         ------ move occurs because `router` has type `Router`, which does not implement the `Copy` trait
34 |
35 |     &router.route("/", get(handler));
   |      ------ value moved here
...
55 |         .serve(router.into_make_service())
   |                ^^^^^^ value used here after move

How can I fix this?

Should I use .clone()?

I tried with &router but I still get the error.



Solution 1:[1]

Here is simplified code (Axum does the same thing). route takes ownership but also returns it.

#[derive(Debug)]
struct Router {
    list: Vec<String>,
}

impl Router {
    fn new() -> Self {
        Router { list: vec![] }
    }

    fn route(mut self, path: String) -> Self {
        self.list.push(path);
        self
    }
}

fn main() {
    let mut router = Router::new().route("/1".to_owned()).route("/2".to_owned());

    if true {
        router = router.route("/3".to_owned());
    }

    println!("{:?}", router);
}

So you have to set router in-line, or make it mut and reassign result of route to router variable.

Solution 2:[2]

Using this code it works:

let mut router = Router::new();
router = router.route("/", get(handler));

if true {
    router = router.route(...);
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Đorđe Zeljić
Solution 2 Fred Hors