From 1fb4a5151bd8cfe6de4d8c19e2066a9281a0b61a Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 29 Dec 2021 16:11:27 +0100 Subject: migrate to axum --- backend/src/lib.rs | 95 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 24 deletions(-) (limited to 'backend/src/lib.rs') diff --git a/backend/src/lib.rs b/backend/src/lib.rs index 8807637..665523f 100644 --- a/backend/src/lib.rs +++ b/backend/src/lib.rs @@ -1,10 +1,5 @@ #![feature(proc_macro_hygiene, decl_macro)] -use rocket::{Build, Rocket}; -use rocket_sync_db_pools::database; - -#[macro_use] -extern crate rocket; #[macro_use] extern crate diesel; @@ -12,27 +7,79 @@ pub mod db; pub mod routes; pub mod schema; -#[database("postgresql_database")] -pub struct DbConn(diesel::PgConnection); +use std::ops::Deref; + +use axum; +use bb8::PooledConnection; +use bb8_diesel::{self, DieselConnectionManager}; +use diesel::PgConnection; -#[get("/")] -fn index() -> &'static str { +use axum::{ + async_trait, + extract::{Extension, FromRequest, RequestParts}, + http::StatusCode, + routing::{get, post}, + AddExtensionLayer, Router, +}; + +async fn index_handler() -> &'static str { "Hello, world!" } -pub fn rocket() -> Rocket { - rocket::build() - .mount( - "/", - routes![ - index, - routes::users::register, - routes::users::login, - routes::users::current_user, - routes::bots::create_bot, - routes::bots::get_bot, - routes::bots::upload_bot_code, - ], - ) - .attach(DbConn::fairing()) +type ConnectionPool = bb8::Pool>; + +pub async fn app() -> Router { + let database_url = "postgresql://planetwars:planetwars@localhost/planetwars"; + let manager = DieselConnectionManager::::new(database_url); + let pool = bb8::Pool::builder().build(manager).await.unwrap(); + + let app = Router::new() + .route("/", get(index_handler)) + .route("/users/register", post(routes::users::register)) + .route("/users/login", post(routes::users::login)) + .route("/users/me", get(routes::users::current_user)) + .route("/bots", post(routes::bots::create_bot)) + .route("/bots/:bot_id", get(routes::bots::get_bot)) + .route("/bots/:bot_id/upload", post(routes::bots::upload_bot_code)) + .layer(AddExtensionLayer::new(pool)); + app +} + +// we can also write a custom extractor that grabs a connection from the pool +// which setup is appropriate depends on your application +pub struct DatabaseConnection(PooledConnection<'static, DieselConnectionManager>); + +impl Deref for DatabaseConnection { + type Target = PooledConnection<'static, DieselConnectionManager>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[async_trait] +impl FromRequest for DatabaseConnection +where + B: Send, +{ + type Rejection = (StatusCode, String); + + async fn from_request(req: &mut RequestParts) -> Result { + let Extension(pool) = Extension::::from_request(req) + .await + .map_err(internal_error)?; + + let conn = pool.get_owned().await.map_err(internal_error)?; + + Ok(Self(conn)) + } +} + +/// Utility function for mapping any error into a `500 Internal Server Error` +/// response. +fn internal_error(err: E) -> (StatusCode, String) +where + E: std::error::Error, +{ + (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()) } -- cgit v1.2.3