//! # Rust Letter Backend //! //! `rust_letter_be` handles the backend execution using Rocket. #[macro_use] extern crate rocket; /// A module that handles the backend for the site. pub mod web_app_backend { use rocket::fs::FileServer; use rocket::http::{Cookie, CookieJar}; use rocket::response::Redirect; use rocket::{Build, Rocket}; use rocket_dyn_templates::{context, Template}; use void_fe::void_app::{self, DarkModeProps, PoemRequest, VirtualDom}; #[get("/")] async fn index(cookies: &CookieJar<'_>) -> Template { let dark_mode = match cookies.get("dark-mode") { Some(c) => { if c.value() == "true" { true } else if c.value() == "false" { false } else { false } } None => false, }; let mut vdom = VirtualDom::new_with_props( void_app::HomePage, DarkModeProps { slug: Some(String::new()), dark_mode, }, ); let _ = vdom.rebuild(); let output = dioxus_ssr::render(&vdom); Template::render( "index", context! { app_title: "A Letter to the Void", style_include: "", test: &output, dark_mode: match dark_mode { true => "dark", false => "" }, }, ) } #[get("/toggle-dark-mode")] async fn dark_mode_root(cookies: &CookieJar<'_>) -> Redirect { match cookies.get("dark-mode") { Some(_) => cookies.remove(Cookie::named("dark-mode")), None => cookies.add(Cookie::new("dark-mode", "true")), }; Redirect::to("/") } #[get("/")] async fn poem_list(cookies: &CookieJar<'_>) -> Template { let dark_mode = match cookies.get("dark-mode") { Some(c) => { if c.value() == "true" { true } else if c.value() == "false" { false } else { false } } None => false, }; let mut vdom = VirtualDom::new_with_props( void_app::PoemListPage, DarkModeProps { slug: Some(String::from("/poems")), dark_mode, }, ); let _ = vdom.rebuild(); let output = dioxus_ssr::render(&vdom); Template::render( "index", context! { app_title: "A Letter to the Void", style_include: "", test: &output, dark_mode: match dark_mode { true => "dark", false => "" }, }, ) } #[get("/toggle-dark-mode")] async fn poems_dark_mode(cookies: &CookieJar<'_>) -> Redirect { match cookies.get("dark-mode") { Some(_) => cookies.remove(Cookie::named("dark-mode")), None => cookies.add(Cookie::new("dark-mode", "true")), }; Redirect::to("/poems/") } #[get("//toggle-dark-mode")] async fn entry_dark_mode(cookies: &CookieJar<'_>, entry: &str) -> Redirect { match cookies.get("dark-mode") { Some(_) => cookies.remove(Cookie::named("dark-mode")), None => cookies.add(Cookie::new("dark-mode", "true")), }; Redirect::to(format!("/poems/{entry}")) } #[get("/")] async fn latest_entry() -> Redirect { let slug = void_app::get_latest_entry(); let uri = String::from("/poems/".to_string() + slug.as_str()); Redirect::to(uri) } #[get("/")] async fn oldest_entry() -> Redirect { let slug = void_app::get_oldest_entry(); let uri = String::from("/poems/".to_string() + slug.as_str()); Redirect::to(uri) } #[get("/?")] async fn previous_entry(current: &str) -> Redirect { let previous = void_app::get_previous_entry(current.to_string()).expect("There is a previous entry."); let uri = String::from("/poems/".to_string() + previous.as_str()); Redirect::to(uri) } #[get("/?")] async fn next_entry(current: &str) -> Redirect { let next = void_app::get_next_entry(current.to_string()).expect("There is a next entry."); let uri = String::from("/poems/".to_string() + next.as_str()); Redirect::to(uri) } #[get("/")] async fn poem(cookies: &CookieJar<'_>, entry: &str) -> Template { let dark_mode = match cookies.get("dark-mode") { Some(c) => { if c.value() == "true" { true } else if c.value() == "false" { false } else { false } } None => false, }; let mut vdom = VirtualDom::new_with_props( void_app::PoemPage, PoemRequest { slug: entry.to_string(), dark_mode: Some(dark_mode), }, ); let _ = vdom.rebuild(); let output = dioxus_ssr::render(&vdom); Template::render( "index", context! { app_title: "A Letter to the Void", style_include: "", test: &output, dark_mode: match dark_mode { true => "dark", false => "" }, }, ) } /// This runs `rocket::build()` with the needed mounts and routes. pub async fn build_rocket() -> Rocket { rocket::build() .mount("/images", FileServer::from("public/images")) .mount("/styles", FileServer::from("public/styles")) .mount("/fonts", FileServer::from("public/fonts")) .mount("/poems/oldest", routes![oldest_entry]) .mount("/poems/previous", routes![previous_entry]) .mount("/poems/next", routes![next_entry]) .mount("/poems/latest", routes![latest_entry]) .mount( "/poems", routes![poems_dark_mode, poem_list, entry_dark_mode, poem], ) .mount("/", routes![dark_mode_root, index]) .attach(Template::fairing()) } }