From 22bac37fcaa1b1cdf8755754184ec8b3ace313b1 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Thu, 11 Jan 2018 22:41:09 +0100 Subject: Drop the lib. The misc stuff from the lib root was moved to the utils module (terrible name, it's meant to be temporary.) The modules under the lib has been moved directly under the app. --- src/lib.rs | 86 ------------------------------------------------------ src/main.rs | 19 +++++++----- src/models/post.rs | 13 +++++---- src/posts.rs | 11 +++---- src/utils/mod.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+), 104 deletions(-) delete mode 100644 src/lib.rs create mode 100644 src/utils/mod.rs diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index ec821e6..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,86 +0,0 @@ -#![feature(plugin, custom_derive)] -#![plugin(rocket_codegen)] - -#[macro_use] extern crate diesel_codegen; -#[macro_use] extern crate diesel; -#[macro_use] extern crate serde_derive; - -extern crate dotenv; -extern crate r2d2_diesel; -extern crate r2d2; -extern crate rocket; - -pub mod models; -pub mod schema; - -use diesel::pg::PgConnection; -use r2d2_diesel::ConnectionManager; -use dotenv::dotenv; -use std::env; - -// An alias to the type for a pool of Diesel PostgreSql connections. -type Pool = r2d2::Pool>; - -/// Initializes a database pool. -pub fn init_db_pool() -> Pool { - dotenv().ok(); - - let config = r2d2::Config::default(); - let dburl = env::var("DATABASE_URL") - .expect("DATABASE_URL environment variable must be set"); - - let manager = ConnectionManager::::new(dburl); - r2d2::Pool::new(config, manager).expect("db pool") -} - -use std::ops::Deref; -use rocket::http::Status; -use rocket::request::{self, FromRequest}; -use rocket::{Request, State, Outcome}; - -// Connection request guard type: a wrapper around an r2d2 pooled connection. -pub struct DbConn(pub r2d2::PooledConnection>); - -/// Attempts to retrieve a single connection from the managed database pool. If -/// no pool is currently managed, fails with an `InternalServerError` status. If -/// no connections are available, fails with a `ServiceUnavailable` status. -impl<'a, 'r> FromRequest<'a, 'r> for DbConn { - type Error = (); - - fn from_request(request: &'a Request<'r>) -> request::Outcome { - let pool = request.guard::>()?; - match pool.get() { - Ok(conn) => Outcome::Success(DbConn(conn)), - Err(_) => Outcome::Failure((Status::ServiceUnavailable, ())) - } - } -} - -// For the convenience of using an &DbConn as an &SqliteConnection. -impl Deref for DbConn { - type Target = PgConnection; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -#[macro_export] -macro_rules! implement_responder_for { - // Implement a responder for the given template type - // - // Seems I can't add the lifetime after the matcher, - // like this: `$template_type<'a>` - // So it will have to be passed in to the argument at - // the macro incovation instead. - ($template_type:ty) => ( - impl<'a> ::rocket::response::Responder<'a> for $template_type { - fn respond_to(self, _: &::rocket::Request) -> Result<::rocket::Response<'static>, ::rocket::http::Status> { - ::rocket::Response::build() - .header(::rocket::http::ContentType::HTML) - .sized_body(::std::io::Cursor::new(format!("{}", &self))) - .ok() - } - } - ) -} diff --git a/src/main.rs b/src/main.rs index 5084fbc..109d7d1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,22 @@ -#![feature(plugin)] +#![feature(plugin, custom_derive)] #![plugin(rocket_codegen)] -#[macro_use] extern crate rocket_blog; #[macro_use] extern crate bart_derive; +#[macro_use] extern crate diesel_codegen; +#[macro_use] extern crate diesel; #[macro_use] extern crate serde_derive; -extern crate diesel; +extern crate dotenv; +extern crate r2d2; +extern crate r2d2_diesel; extern crate rocket; extern crate rocket_contrib; -use rocket_blog::models; use rocket_contrib::Json; +#[macro_use] mod utils; +mod models; +mod schema; mod posts; #[derive(BartDisplay, Serialize)] @@ -24,18 +29,18 @@ struct IndexTemplate<'a> { implement_responder_for!(IndexTemplate<'a>); #[get("/", format = "text/html")] -fn index<'a>(conn: rocket_blog::DbConn) -> IndexTemplate<'a> { +fn index<'a>(conn: utils::DbConn) -> IndexTemplate<'a> { IndexTemplate { title: "Bloggen", posts: models::Post::get_all(conn) } } #[get("/", format = "application/json")] -fn index_json(conn: rocket_blog::DbConn) -> Json> { +fn index_json(conn: utils::DbConn) -> Json> { Json(models::Post::get_all(conn)) } fn main() { rocket::ignite() - .manage(rocket_blog::init_db_pool()) + .manage(utils::init_db_pool()) .mount("/", routes![index, index_json]) .mount("/posts", routes![posts::new, posts::create, posts::show, posts::edit, posts::update]) .launch(); diff --git a/src/models/post.rs b/src/models/post.rs index b8453ce..922dbca 100644 --- a/src/models/post.rs +++ b/src/models/post.rs @@ -1,6 +1,7 @@ -use ::schema::posts; +use schema::posts; use diesel::prelude::*; use diesel::{self, ExecuteDsl}; +use utils; #[derive(AsChangeset, FromForm, Identifiable, Serialize, Queryable)] pub struct Post { @@ -19,7 +20,7 @@ pub struct NewPost { } impl Post { - pub fn get_all(conn: ::DbConn) -> Vec { + pub fn get_all(conn: utils::DbConn) -> Vec { use ::schema::posts::dsl::*; posts.filter(published.eq(false)) .limit(5) @@ -27,25 +28,25 @@ impl Post { .expect("Error loading posts") } - fn get_internal(post_id: i32, conn: &::DbConn) -> Post { + fn get_internal(post_id: i32, conn: &utils::DbConn) -> Post { use ::schema::posts::dsl::*; posts.find(post_id) .get_result(&**conn) .expect(&format!("Unable to find post with id={}", post_id)) } - pub fn get(post_id: i32, conn: ::DbConn) -> Post { + pub fn get(post_id: i32, conn: utils::DbConn) -> Post { Post::get_internal(post_id, &conn) } - pub fn create(new_post: &NewPost, conn: ::DbConn) { + pub fn create(new_post: &NewPost, conn: utils::DbConn) { diesel::insert(new_post) .into(posts::table) .execute(&*conn) .expect("Error saving post."); } - pub fn update(updated_post: &Post, conn: ::DbConn) { + pub fn update(updated_post: &Post, conn: utils::DbConn) { let p = Post::get_internal(updated_post.id, &conn); diesel::update(&p) .set(updated_post) diff --git a/src/posts.rs b/src/posts.rs index 859cce5..fde08a8 100644 --- a/src/posts.rs +++ b/src/posts.rs @@ -1,5 +1,6 @@ use rocket::request::Form; use rocket::response::Redirect; +use utils; #[derive(BartDisplay)] #[template = "templates/new_post.html"] @@ -11,12 +12,12 @@ pub struct NewPostTemplate<'a> { implement_responder_for!(NewPostTemplate<'a>); #[get("/new", format = "text/html")] -fn new<'a>(_conn: ::rocket_blog::DbConn) -> NewPostTemplate<'a> { +fn new<'a>(_conn: utils::DbConn) -> NewPostTemplate<'a> { NewPostTemplate { title: "Bloggen", post: Default::default() } } #[post("/create", data="")] -fn create(post: Form<::models::NewPost>, conn: ::rocket_blog::DbConn) -> Redirect { +fn create(post: Form<::models::NewPost>, conn: utils::DbConn) -> Redirect { ::models::Post::create(post.get(), conn); Redirect::to("/") } @@ -30,7 +31,7 @@ pub struct ShowPostTemplate { implement_responder_for!(ShowPostTemplate); #[get("/", format = "text/html")] -fn show<'a>(id: i32, conn: ::rocket_blog::DbConn) -> ShowPostTemplate { +fn show<'a>(id: i32, conn: utils::DbConn) -> ShowPostTemplate { let p = ::models::Post::get(id, conn); ShowPostTemplate { post: p } } @@ -44,13 +45,13 @@ pub struct EditPostTemplate { implement_responder_for!(EditPostTemplate); #[get("//edit", format = "text/html")] -fn edit(id: i32, conn: ::rocket_blog::DbConn) -> EditPostTemplate { +fn edit(id: i32, conn: utils::DbConn) -> EditPostTemplate { let p = ::models::Post::get(id, conn); EditPostTemplate { post: p } } #[post("/update", data="")] -fn update(post: Form<::models::Post>, conn: ::rocket_blog::DbConn) -> Redirect { +fn update(post: Form<::models::Post>, conn: utils::DbConn) -> Redirect { ::models::Post::update(post.get(), conn); Redirect::to("/") } diff --git a/src/utils/mod.rs b/src/utils/mod.rs new file mode 100644 index 0000000..1d697fe --- /dev/null +++ b/src/utils/mod.rs @@ -0,0 +1,71 @@ +use diesel::pg::PgConnection; +use r2d2; +use r2d2_diesel::ConnectionManager; +use dotenv::dotenv; +use std::env; + +// An alias to the type for a pool of Diesel PostgreSql connections. +type Pool = r2d2::Pool>; + +/// Initializes a database pool. +pub fn init_db_pool() -> Pool { + dotenv().ok(); + + let config = r2d2::Config::default(); + let dburl = env::var("DATABASE_URL") + .expect("DATABASE_URL environment variable must be set"); + + let manager = ConnectionManager::::new(dburl); + r2d2::Pool::new(config, manager).expect("db pool") +} + +use std::ops::Deref; +use rocket::http::Status; +use rocket::request::{self, FromRequest}; +use rocket::{Request, State, Outcome}; + +// Connection request guard type: a wrapper around an r2d2 pooled connection. +pub struct DbConn(pub r2d2::PooledConnection>); + +/// Attempts to retrieve a single connection from the managed database pool. If +/// no pool is currently managed, fails with an `InternalServerError` status. If +/// no connections are available, fails with a `ServiceUnavailable` status. +impl<'a, 'r> FromRequest<'a, 'r> for DbConn { + type Error = (); + + fn from_request(request: &'a Request<'r>) -> request::Outcome { + let pool = request.guard::>()?; + match pool.get() { + Ok(conn) => Outcome::Success(DbConn(conn)), + Err(_) => Outcome::Failure((Status::ServiceUnavailable, ())) + } + } +} + +// For the convenience of using an &DbConn as an &SqliteConnection. +impl Deref for DbConn { + type Target = PgConnection; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +macro_rules! implement_responder_for { + // Implement a responder for the given template type + // + // Seems I can't add the lifetime after the matcher, + // like this: `$template_type<'a>` + // So it will have to be passed in to the argument at + // the macro incovation instead. + ($template_type:ty) => ( + impl<'a> ::rocket::response::Responder<'a> for $template_type { + fn respond_to(self, _: &::rocket::Request) -> Result<::rocket::Response<'static>, ::rocket::http::Status> { + ::rocket::Response::build() + .header(::rocket::http::ContentType::HTML) + .sized_body(::std::io::Cursor::new(format!("{}", &self))) + .ok() + } + } + ) +} -- cgit v1.2.3