I'm learning Rust, and I have problem with understanding passing objects by reference and lifetimes. I decided to create a simple REST (Axum + HashMap as database). I got a problem, because I do not know how to properly set database instance to save and retrieve from.
I have database.rs
file:
pub struct Database<'a> {
pub players: HashMap<u32, &'a Player>
}
impl<'a> Database<'a> {
pub fn save_to_db(&mut self, player: &'a Player) -> () {
self.players.insert(player.id, player);
}
}
File routes.rs
which get JSON
passed from user:
pub struct Routes<'a> {
pub(crate) database: Database<'a>
}
impl<'a> Routes<'a> {
pub async fn create_player(&mut self, Json(payload): Json<CreatePlayer>) -> impl IntoResponse {
let player = Player {
id: 1,
name: payload.name,
age: payload.age,
position: payload.position,
};
self.database.save_to_db(&player);
(StatusCode::OK, Json(player))
}
pub async fn get_player(Path(_): Path<String>) -> impl IntoResponse {
let player = Player {
id: 1,
name: String::from("Some Player"),
age: 28,
position: String::from("midfielder"),
};
(StatusCode::OK, Json(player))
}
}
and main.rs
to run it all:
mod http;
use crate::http::routes::Routes;
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
let routes = Routes {
database: Database {
players: HashMap::new()
}
};
let router = Router::new()
.route("/player/:id", get(routes.get_player()))
.route("/player", post(routes.create_player));
axum::Server::bind(&"0.0.0.0:8080".parse().unwrap())
.serve(router.into_make_service())
.await
.unwrap();
}
The problem is with these lines:
.route("/player/:id", get(routes.get_player()))
.route("/player", post(routes.create_player));
It is impossible in Axum to pass my database
object here. I tried also to move this:
let routes = Routes {
database: Database {
players: HashMap::new()
}
};
into routes.rs
file but the problem would be same - could not pass self
into get_player
and create_player
methods.
How should I create an instance of my HashMap
database and how to pass it correctly through the whole application?