use crate::db::{Dao, TenebrousDbConn}; use crate::errors::Error; use crate::models::characters::{CharacterDataType, DynCharacterData, Visibility}; use crate::models::users::User; use rocket::request::Form; use rocket::response::Redirect; use rocket_contrib::templates::Template; use serde::Serialize; use std::collections::HashMap; pub(crate) fn routes() -> Vec { routes![ view_character, new_character, create_new_character, new_character_not_logged_in, edit_character ] } #[derive(FromForm)] struct NewCharacterForm { name: String, //TODO add game system } #[derive(Serialize)] struct ViewCharacterTemplate<'a> { pub name: &'a str, pub username: &'a str, pub sheet: Box, } #[get("//")] fn view_character( character_id: i32, username: String, conn: TenebrousDbConn, logged_in_user: Option<&User>, ) -> Result { let user = conn.load_user(&username)?.ok_or(Error::NotFound)?; let character = conn .load_character(character_id)? .and_then(|c| c.as_visible_for(logged_in_user)) .ok_or(Error::NotFound)?; let context = ViewCharacterTemplate { name: &character.character_name, username: &user.username, sheet: character.dyn_deserialize()?, }; Ok(Template::render("view_character", context)) } #[get("/new")] fn new_character(logged_in_user: &User, conn: TenebrousDbConn) -> Result { let context = HashMap::::new(); Ok(Template::render("new_character", context)) } #[post("/new", data = "
")] fn create_new_character( form: Form, logged_in_user: &User, conn: TenebrousDbConn, ) -> Result { //TODO redirect to character edit page //TODO redirect back to new character page with an error and filled-out form if validation errors. //TODO add game system. use crate::models::characters::NewCharacter; use crate::models::proto::cofd::CofdSheet; use prost::bytes::BytesMut; use prost::Message; let mut new_character = CofdSheet::default(); new_character.strength = 100; let mut buf = BytesMut::with_capacity(std::mem::size_of_val(&new_character)); new_character.encode(&mut buf)?; let insert = NewCharacter { user_id: logged_in_user.id, viewable: true, character_name: &form.name, data_type: CharacterDataType::ChroniclesOfDarknessV1, data_version: 1, data: &buf, }; conn.insert_character(insert)?; Ok(super::common::redirect_to_index()) } #[get("/new", rank = 2)] fn new_character_not_logged_in() -> Redirect { super::common::redirect_to_login() } #[get("///edit")] fn edit_character( character_id: i32, owner: String, logged_in_user: Option<&User>, conn: TenebrousDbConn, ) -> Result { let owner = conn.load_user(&owner)?.ok_or(Error::NotFound)?; let logged_in_user = logged_in_user.ok_or(Error::NotLoggedIn)?; let character = conn.load_character(character_id)?.ok_or(Error::NotFound)?; if logged_in_user != &owner { return Err(Error::NoPermission); } let mut context = HashMap::new(); context.insert("name", character.character_name); context.insert("username", owner.username); Ok(Template::render("view_character", context)) }