about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@gmail.com>2018-04-14T20·06+0200
committerVincent Ambo <github@tazj.in>2018-04-14T20·21+0200
commit4132869277656437f1f62869a2b1676d4c1c42d7 (patch)
tree6ee6a8302e4712bc8aca47e8c021063ad338b0bf /src
parentdae97fdaf5a9541895d9719f1f58902cca846e2b (diff)
feat: Implement search result view & enable search
Implements a very simple and currently kinda broken-looking search
result view.
Diffstat (limited to 'src')
-rw-r--r--src/handlers.rs16
-rw-r--r--src/main.rs1
-rw-r--r--src/models.rs2
-rw-r--r--src/render.rs21
4 files changed, 39 insertions, 1 deletions
diff --git a/src/handlers.rs b/src/handlers.rs
index 33f33deccb..02ff99394e 100644
--- a/src/handlers.rs
+++ b/src/handlers.rs
@@ -176,6 +176,22 @@ pub fn reply_thread(state: State<AppState>,
         .responder()
 }
 
+/// This handler executes a full-text search on the forum database and
+/// displays the results to the user.
+pub fn search_forum(state: State<AppState>,
+                    query: Form<SearchPosts>) -> ConverseResponse {
+    let query_string = query.0.query.clone();
+    state.db.send(query.0)
+        .flatten()
+        .and_then(move |results| state.renderer.send(SearchResultPage {
+            results,
+            query: query_string,
+        }).from_err())
+        .flatten()
+        .map(|res| HttpResponse::Ok().content_type(HTML).body(res))
+        .responder()
+}
+
 /// This handler initiates an OIDC login.
 pub fn login(state: State<AppState>) -> ConverseResponse {
     state.oidc.send(GetLoginUrl)
diff --git a/src/main.rs b/src/main.rs
index 9f4eea03fa..92eeca48df 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -153,6 +153,7 @@ fn main() {
             .resource("/thread/submit", |r| r.method(Method::POST).with3(submit_thread))
             .resource("/thread/reply", |r| r.method(Method::POST).with3(reply_thread))
             .resource("/thread/{id}", |r| r.method(Method::GET).with2(forum_thread))
+            .resource("/search", |r| r.method(Method::POST).with2(search_forum))
             .resource("/oidc/login", |r| r.method(Method::GET).with(login))
             .resource("/oidc/callback", |r| r.method(Method::POST).with3(callback));
 
diff --git a/src/models.rs b/src/models.rs
index 927a785136..dfadd53fd3 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -74,7 +74,7 @@ pub struct NewPost {
 /// This struct models the response of a full-text search query. It
 /// does not use a table/schema definition struct like the other
 /// tables, as no table of this type actually exists.
-#[derive(QueryableByName, Debug)]
+#[derive(QueryableByName, Debug, Serialize)]
 pub struct SearchResult {
     #[sql_type = "Integer"]
     pub post_id: i32,
diff --git a/src/render.rs b/src/render.rs
index 186b96d247..537cab59da 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -175,3 +175,24 @@ impl Handler<NewThreadPage> for Renderer {
         Ok(self.tera.render("new-thread.html", &ctx)?)
     }
 }
+
+/// Message used to render search results
+pub struct SearchResultPage {
+    pub query: String,
+    pub results: Vec<SearchResult>,
+}
+
+impl Message for SearchResultPage {
+    type Result = Result<String>;
+}
+
+impl Handler<SearchResultPage> for Renderer {
+    type Result = Result<String>;
+
+    fn handle(&mut self, msg: SearchResultPage, _: &mut Self::Context) -> Self::Result {
+        let mut ctx = Context::new();
+        ctx.add("query", &msg.query);
+        ctx.add("results", &msg.results);
+        Ok(self.tera.render("search.html", &ctx)?)
+    }
+}