aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils
diff options
context:
space:
mode:
authorHarald Eilertsen <haraldei@anduin.net>2018-01-11 22:41:09 +0100
committerHarald Eilertsen <haraldei@anduin.net>2018-01-11 22:41:09 +0100
commit22bac37fcaa1b1cdf8755754184ec8b3ace313b1 (patch)
tree41e6b4ec69b173313c257d9c74b8e62fce6028b1 /src/utils
parent757770635c4c2537b03f9b1fb1576a8bf4609a72 (diff)
downloadrocket-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.rs71
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()
+ }
+ }
+ )
+}