From 3edf5d60f54bfd0cd2c818e5fb1ca133e324325d Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Thu, 30 Dec 2021 11:45:59 +0100 Subject: rename to planetwars-server --- planetwars-server/src/lib.rs | 85 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 planetwars-server/src/lib.rs (limited to 'planetwars-server/src/lib.rs') diff --git a/planetwars-server/src/lib.rs b/planetwars-server/src/lib.rs new file mode 100644 index 0000000..665523f --- /dev/null +++ b/planetwars-server/src/lib.rs @@ -0,0 +1,85 @@ +#![feature(proc_macro_hygiene, decl_macro)] + +#[macro_use] +extern crate diesel; + +pub mod db; +pub mod routes; +pub mod schema; + +use std::ops::Deref; + +use axum; +use bb8::PooledConnection; +use bb8_diesel::{self, DieselConnectionManager}; +use diesel::PgConnection; + +use axum::{ + async_trait, + extract::{Extension, FromRequest, RequestParts}, + http::StatusCode, + routing::{get, post}, + AddExtensionLayer, Router, +}; + +async fn index_handler() -> &'static str { + "Hello, world!" +} + +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