aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFuwn <[email protected]>2020-11-19 05:16:45 +0000
committerFuwn <[email protected]>2020-11-19 05:16:45 +0000
commit4caa665aa3f323571c8f791588c7e1baeaaf6dc7 (patch)
tree8fa9038d865b726d1d6b9508acd5cd3ef834b691 /src
parentCreate LICENSE.md (diff)
downloadchan-4caa665aa3f323571c8f791588c7e1baeaaf6dc7.tar.xz
chan-4caa665aa3f323571c8f791588c7e1baeaaf6dc7.zip
repo: :star:
Diffstat (limited to 'src')
-rw-r--r--src/api.rs20
-rw-r--r--src/db.rs43
-rw-r--r--src/main.rs29
-rw-r--r--src/ui.rs29
4 files changed, 121 insertions, 0 deletions
diff --git a/src/api.rs b/src/api.rs
new file mode 100644
index 0000000..8d8d2f2
--- /dev/null
+++ b/src/api.rs
@@ -0,0 +1,20 @@
+use rocket::request::Form;
+use rocket::response::Redirect;
+
+use crate::db::*;
+
+// POST: Create a new thread.
+#[post("/post", data = "<thread>")]
+pub fn post(thread: Form<Thread>) -> Redirect {
+ // Pretty rudimentary error handling.
+ match new_thread(Thread {
+ name: thread.name.clone(),
+ comment: thread.comment.clone(),
+ }) {
+ Ok(()) => { },
+ Err(why) => println!("Error creating new thread: {}", why)
+ }
+
+ // Redirect to all posts.
+ Redirect::to("/threads")
+}
diff --git a/src/db.rs b/src/db.rs
new file mode 100644
index 0000000..7a5a85d
--- /dev/null
+++ b/src/db.rs
@@ -0,0 +1,43 @@
+use rusqlite::{params, Connection, Result, Error as SQLError};
+
+/// The format a valid SQLlite thread entry should have.
+#[derive(FromForm, Debug, Serialize, Deserialize)]
+pub struct Thread {
+ pub name: String,
+ pub comment: String
+}
+
+/// Create a new thread in the SQLite database.
+pub fn new_thread(mut thread: Thread) -> Result<()> {
+ // Open SQLite database file.
+ let db = Connection::open("chan.db")?;
+
+ // If the name field in the POST request is empty, user should be "anonymous".
+ if thread.name == "" {
+ thread.name = "anonymous".to_owned();
+ }
+
+ // Add thread entry to database.
+ db.execute(
+ "INSERT INTO thread (name, comment) VALUES (?1, ?2)",
+ params![thread.name, thread.comment]
+ )?;
+
+ Ok(())
+}
+
+/// Get all threads from the SQLite databse.
+pub fn get_threads() -> Result<Vec<Thread>, SQLError> {
+ // Open SQLite database file.
+ let db = Connection::open("chan.db")?;
+
+ // Get all entries from the thread table.
+ let mut statement = db.prepare("SELECT name, comment FROM thread")?;
+ let threads = statement.query_map(params![], |row| {
+ Ok(Thread {
+ name: row.get(0)?,
+ comment: row.get(1)?
+ })
+ })?;
+ threads.collect()
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..f5fbd56
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,29 @@
+#![feature(proc_macro_hygiene, decl_macro)]
+
+#[macro_use] extern crate rocket;
+#[macro_use] extern crate serde_derive;
+extern crate rocket_contrib;
+extern crate serde_json;
+
+mod api;
+mod ui;
+mod db;
+
+use rocket_contrib::templates::Template;
+
+fn main() {
+ rocket::ignite()
+ .attach(Template::fairing())
+ .register(catchers![
+ ui::not_found
+ ])
+ .mount("/", routes![
+ ui::index,
+ ui::make_post,
+ ui::threads
+ ])
+ .mount("/api/v1/", routes![
+ api::post
+ ])
+ .launch();
+}
diff --git a/src/ui.rs b/src/ui.rs
new file mode 100644
index 0000000..0a054e7
--- /dev/null
+++ b/src/ui.rs
@@ -0,0 +1,29 @@
+use rocket_contrib::templates::Template;
+use rocket::response::Redirect;
+
+use crate::db::*;
+
+// GET: Index.
+#[get("/")]
+pub fn index() -> Template {
+ Template::render("index", &())
+}
+
+#[catch(404)]
+pub fn not_found() -> Redirect {
+ Redirect::to("/")
+}
+
+// GET: Make a new thread.
+#[get("/post")]
+pub fn make_post() -> Template {
+ Template::render("post", &())
+}
+
+// GET: Check out all the threads.
+#[get("/threads")]
+pub fn threads() -> Template {
+ let context = get_threads().unwrap();
+ let threads = serde_json::json!(&context);
+ Template::render("threads", threads)
+}