about summary refs log tree commit diff
path: root/src/handlers.rs
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 /src/handlers.rs
parent67a0642f8c9b9f90c71ab8ca64be8e6ae15ff830 (diff)
refactor(main): Move handlers into separate handler module
Diffstat (limited to 'src/handlers.rs')
-rw-r--r--src/handlers.rs76
1 files changed, 76 insertions, 0 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()
+}