mod logger; extern crate rocket; extern crate rocket_dyn_templates; use rocket::response::content::RawJson; use rocket::{get, post, launch, build, routes}; use rocket::fs::FileServer; use rocket_dyn_templates::{Template, context}; use rocket::serde::{Deserialize, Serialize, json::Json}; use chrono::Local; use std::borrow::Cow; use std::io::Write; use std::path::Path; use std::fs::File; use std::fs::read_to_string; use serde_json::{Value, json}; use crate::logger::iwakulog::{LogLevel, log}; const ASSETS_DIR: &str = "./assets"; const GUEST_MESSAGES: &str = "./guests.json"; const DATE_TIME_FORMAT: &str = "%Y-%m%d | %H:%M"; #[derive(Serialize, Deserialize)] #[serde(crate = "rocket::serde")] struct GuestMessage<'r> { name: Cow<'r, str>, body: Cow<'r, str>, } fn check_file(path: &str) -> bool { Path::new(path).exists() } fn read_guest_messages() -> Result> { let file = read_to_string(GUEST_MESSAGES)?; let json: Value = serde_json::from_str(&file)?; Ok(json) } fn post_guest_message(name: &str, body: &str) { let mut guest_json = match read_guest_messages() { Ok(x) => x, Err(x) => panic!("Error while reading guest messages: {x:?}") }; let messages = guest_json["messages"] .as_array_mut() .expect("Object is not an array?"); let date = Local::now().format(DATE_TIME_FORMAT); messages.push(json!({ "name": name, "body": body, "date": date.to_string(), })); let mut file = File::create(GUEST_MESSAGES).expect("Couldn't read msgs"); file.write_all(guest_json.to_string().as_bytes()).expect("wah"); } #[get("/")] fn index() -> Template { Template::render("index", context! {}) } #[post("/post_message", data = "")] fn post_msg(input: Json>) { post_guest_message(&input.name, &input.body); return; } #[get("/guestbook")] fn guests() -> Template { let guest_json = match read_guest_messages() { Ok(x) => x, Err(x) => panic!("Error while reading guest messages: {x:?}") }; Template::render("guest", &guest_json) } #[launch] fn rocket() -> _ { if !check_file(GUEST_MESSAGES) { log(LogLevel::Warn, format!("Guest messages file ({}) has not been found. Creating a new one.", GUEST_MESSAGES).as_str()); let mut file = File::create(GUEST_MESSAGES).expect("Failed to create file."); file.write_all(b"{\"messages\":[]}").expect("Failed to write to file."); } build() .mount("/", routes![index, guests, post_msg]) .mount("/assets", FileServer::from(ASSETS_DIR)) .attach(Template::fairing()) }