diff options
author | Harald Eilertsen <haraldei@anduin.net> | 2018-01-11 22:41:09 +0100 |
---|---|---|
committer | Harald Eilertsen <haraldei@anduin.net> | 2018-01-11 22:41:09 +0100 |
commit | 22bac37fcaa1b1cdf8755754184ec8b3ace313b1 (patch) | |
tree | 41e6b4ec69b173313c257d9c74b8e62fce6028b1 /src/utils | |
parent | 757770635c4c2537b03f9b1fb1576a8bf4609a72 (diff) | |
download | rocket-blog-22bac37fcaa1b1cdf8755754184ec8b3ace313b1.tar.gz rocket-blog-22bac37fcaa1b1cdf8755754184ec8b3ace313b1.tar.bz2 rocket-blog-22bac37fcaa1b1cdf8755754184ec8b3ace313b1.zip |
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.
Diffstat (limited to 'src/utils')
-rw-r--r-- | src/utils/mod.rs | 71 |
1 files changed, 71 insertions, 0 deletions
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<ConnectionManager<PgConnection>>; + +/// 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::<PgConnection>::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<ConnectionManager<PgConnection>>); + +/// 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<DbConn, ()> { + let pool = request.guard::<State<Pool>>()?; + 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() + } + } + ) +} |