diff options
author | Vincent Ambo <tazjin@gmail.com> | 2018-04-11T10·18+0200 |
---|---|---|
committer | Vincent Ambo <tazjin@gmail.com> | 2018-04-11T10·18+0200 |
commit | 1cce37446b3dbc558ffe82b1b1728279dec92175 (patch) | |
tree | 76758a111a2d54c44c324e17a4f2abc858f04b8e | |
parent | fe7e5e48b5702a0547b3008e06a1f0c04d88e3bf (diff) |
refactor(handlers): Use rendering actor for page renders
This currently breaks error handling in page render flows. To fix it properly, the database actor should return failable futures instead of `Result<T>` wrapped in a future.
-rw-r--r-- | src/handlers.rs | 72 | ||||
-rw-r--r-- | todo.org | 5 |
2 files changed, 31 insertions, 46 deletions
diff --git a/src/handlers.rs b/src/handlers.rs index 3af8a8c40929..9732414b31cf 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -5,7 +5,7 @@ //! the tera templates stored in the `/templates` directory in the //! project root. -use actix::prelude::{Addr, Syn}; +use actix::prelude::*; use actix_web; use actix_web::*; use actix_web::middleware::{Started, Middleware, RequestSession}; @@ -15,9 +15,12 @@ use futures::Future; use models::*; use oidc::*; use tera; +use render::*; type ConverseResponse = Box<Future<Item=HttpResponse, Error=ConverseError>>; +const HTML: &'static str = "text/html"; + /// Represents the state carried by the web server actors. pub struct AppState { /// Address of the database actor @@ -26,68 +29,47 @@ pub struct AppState { /// Address of the OIDC actor pub oidc: Addr<Syn, OidcExecutor>, - /// Compiled templates - pub tera: tera::Tera, + /// Address of the rendering actor + pub renderer: Addr<Syn, Renderer>, } -/// 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)) -} +// impl AppState { +// fn render_ok<M>(self, msg: M) -> ConverseResponse +// where M: Send + Message, Renderer: Handler<M> { +// self.renderer.send(msg); +// unimplemented!() +// } +// } pub fn forum_index(state: State<AppState>) -> ConverseResponse { state.db.send(ListThreads) + .and_then(move |res| state.renderer.send(IndexPage { threads: res.unwrap() })) .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()) - } - }) + .map(|res| HttpResponse::Ok().content_type(HTML).body(res.unwrap())) .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()) - } + .and_then(move |res| { + let u = res.unwrap(); + state.renderer.send(ThreadPage { + thread: u.0, + posts: u.1, + }) }) + .from_err() + .map(|res| HttpResponse::Ok().content_type(HTML).body(res.unwrap())) .responder() } /// This handler presents the user with the "New Thread" form. -pub fn new_thread(state: State<AppState>) -> Result<HttpResponse> { - let ctx = tera::Context::new(); - let body = state.tera.render("new-thread.html", &ctx)?; - Ok(HttpResponse::Ok() - .content_type("text/html") - .body(body)) +pub fn new_thread(state: State<AppState>) -> ConverseResponse { + state.renderer.send(NewThreadPage).from_err() + .map(|res| HttpResponse::Ok().content_type(HTML).body(res.unwrap())) + .responder() } #[derive(Deserialize)] diff --git a/todo.org b/todo.org index af8fb223a2f3..63ad4ebb0645 100644 --- a/todo.org +++ b/todo.org @@ -1,4 +1,7 @@ +* DONE Pin *-versions in cargo.toml * TODO Configurable number of DB workers -* TODO Pin *-versions in cargo.toml * TODO Match certain types of Diesel errors (esp. for "not found") * TODO Sketch out categories vs. tags system +* TODO Markdown support +* TODO Quote button +* TODO Multiquote buttons |