about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@gmail.com>2018-04-08T16·48+0200
committerVincent Ambo <tazjin@gmail.com>2018-04-08T17·21+0200
commitc8cee945c569d71618b6bce5848233af4c9be18a (patch)
treeade2f3f6491f12a37fea6e4a202ced0f172e79e3
parent67a0642f8c9b9f90c71ab8ca64be8e6ae15ff830 (diff)
refactor(main): Move handlers into separate handler module
-rw-r--r--src/handlers.rs76
-rw-r--r--src/main.rs64
2 files changed, 79 insertions, 61 deletions
diff --git a/src/handlers.rs b/src/handlers.rs
new file mode 100644
index 000000000000..446f59a4f3ac
--- /dev/null
+++ b/src/handlers.rs
@@ -0,0 +1,76 @@
+//! This module contains the implementation of converse's actix-web
+//! HTTP handlers.
+//!
+//! Most handlers have an associated rendering function using one of
+//! the tera templates stored in the `/templates` directory in the
+//! project root.
+
+use tera;
+use actix_web::*;
+use models::*;
+use db::*;
+use actix::prelude::{Addr, Syn};
+use futures::Future;
+use errors::{Result, ConverseError};
+
+type ConverseResponse = Box<Future<Item=HttpResponse, Error=ConverseError>>;
+
+/// Represents the state carried by the web server actors.
+pub struct AppState {
+    /// Address of the database actor
+    pub db: Addr<Syn, DbExecutor>,
+
+    /// Compiled templates
+    pub tera: tera::Tera,
+}
+
+/// This function renders an overview of threads into the default
+/// thread list template.
+fn render_threads(tpl: &tera::Tera, threads: Vec<Thread>) -> Result<HttpResponse> {
+    let mut ctx = tera::Context::new();
+    ctx.add("threads", &threads);
+    let body = tpl.render("index.html", &ctx)?;
+    Ok(HttpResponse::Ok().content_type("text/html").body(body))
+}
+
+pub fn forum_index(state: State<AppState>) -> ConverseResponse {
+    state.db.send(ListThreads)
+        .from_err()
+        .and_then(move |res| match res {
+            Ok(threads) => Ok(render_threads(&state.tera, threads)?),
+            Err(err) => {
+                error!("Error loading threads: {}", err);
+                Ok(HttpResponse::InternalServerError().into())
+            }
+        })
+        .responder()
+}
+
+/// This function renders a single forum thread into the default
+/// thread view.
+fn render_thread(tpl: &tera::Tera, thread: Thread, posts: Vec<Post>)
+                 -> Result<HttpResponse> {
+    let mut ctx = tera::Context::new();
+    ctx.add("thread", &thread);
+    ctx.add("posts", &posts);
+
+    let body = tpl.render("thread.html", &ctx)?;
+    Ok(HttpResponse::Ok()
+        .content_type("text/html")
+        .body(body))
+}
+
+/// This handler retrieves and displays a single forum thread.
+pub fn forum_thread(state: State<AppState>, thread_id: Path<i32>) -> ConverseResponse {
+    let id = thread_id.into_inner();
+    state.db.send(GetThread(id))
+        .from_err()
+        .and_then(move |res| match res {
+            Ok((thread, posts)) => Ok(render_thread(&state.tera, thread, posts)?),
+            Err(err) => {
+                error!("Error loading thread {}: {}", id, err);
+                Ok(HttpResponse::InternalServerError().into())
+            }
+        })
+        .responder()
+}
diff --git a/src/main.rs b/src/main.rs
index 3590975c8e9f..8ce4e1082e4e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -21,74 +21,16 @@ extern crate serde;
 pub mod schema;
 pub mod models;
 pub mod db;
+pub mod handlers;
 
 use actix::prelude::*;
 use actix_web::*;
 use actix_web::http::Method;
-
+use db::*;
 use diesel::pg::PgConnection;
 use diesel::r2d2::{ConnectionManager, Pool};
 use std::env;
-use db::*;
-use futures::Future;
-use models::*;
-
-/// Represents the state carried by the web server actors.
-struct AppState {
-    /// Address of the database actor
-    db: Addr<Syn, DbExecutor>,
-
-    /// Compiled templates
-    tera: tera::Tera,
-}
-
-/// Really inefficient renderer example!
-fn render_threads(tpl: &tera::Tera, threads: Vec<Thread>) -> String {
-    let mut ctx = tera::Context::new();
-    ctx.add("threads", &threads);
-    tpl.render("index.html", &ctx).expect("Oh no")
-}
-
-fn forum_index(state: State<AppState>) -> FutureResponse<HttpResponse> {
-    state.db.send(ListThreads)
-        .from_err()
-        .and_then(move |res| match res {
-            Ok(threads) => Ok(HttpResponse::Ok()
-                              .content_type("text/html")
-                              .body(render_threads(&state.tera, threads))),
-            Err(err) => {
-                error!("Error loading threads: {}", err);
-                Ok(HttpResponse::InternalServerError().into())
-            }
-        })
-        .responder()
-}
-
-fn render_thread(tpl: &tera::Tera, thread: Thread, posts: Vec<Post>) -> HttpResponse {
-    let mut ctx = tera::Context::new();
-    ctx.add("thread", &thread);
-    ctx.add("posts", &posts);
-
-    let body = tpl.render("thread.html", &ctx).expect("Oh no");
-    HttpResponse::Ok()
-        .content_type("text/html")
-        .body(body)
-}
-
-fn forum_thread(state: State<AppState>, thread_id: Path<i32>)
-                -> FutureResponse<HttpResponse> {
-    let id = thread_id.into_inner();
-    state.db.send(GetThread(id))
-        .from_err()
-        .and_then(move |res| match res {
-            Ok((thread, posts)) => Ok(render_thread(&state.tera, thread, posts)),
-            Err(err) => {
-                error!("Error loading thread {}: {}", id, err);
-                Ok(HttpResponse::InternalServerError().into())
-            }
-        })
-        .responder()
-}
+use handlers::*;
 
 fn main() {
     env_logger::init();