use crate::db::{Dao, TenebrousDbConn}; use crate::errors::Error; use crate::models::characters::{Character, CharacterDataType, DynCharacterData, Visibility}; use crate::models::users::User; use rocket_contrib::templates::Template; use std::collections::HashMap; mod new; pub(crate) fn routes() -> Vec { routes![ view_character, new::new_character_page, new::new_character_submit, new::new_character_not_logged_in, edit_character ] } #[derive(Serialize)] struct ViewCharacterTemplate<'a> { pub name: &'a str, pub username: &'a str, pub data_type: &'a CharacterDataType, pub sheet: Box, } fn view_character_template(user: &User, character: Character) -> Result { let character = character.uprade()?; let context = ViewCharacterTemplate { name: &character.character_name, username: &user.username, data_type: &character.data_type, sheet: character.dyn_deserialize()?, }; use CharacterDataType::*; let template = match character.data_type { ChroniclesOfDarknessV1 => Template::render("characters/view_character", context), ChangelingV1 => Template::render("characters/view_changeling_character", context), }; Ok(template) } #[get("//")] async fn view_character( character_id: i32, username: String, conn: TenebrousDbConn, logged_in_user: Option<&User>, ) -> Result { let user = &conn.load_user(username).await?.ok_or(Error::NotFound)?; let character = conn .load_character(character_id) .await? .and_then(|c| c.as_visible_for(logged_in_user)) .ok_or(Error::NotFound)?; let template = view_character_template(user, character)?; Ok(template) } #[get("///edit")] async fn edit_character( character_id: i32, owner: String, logged_in_user: Option<&User>, conn: TenebrousDbConn, ) -> Result { let owner = conn.load_user(owner).await?.ok_or(Error::NotFound)?; let logged_in_user = logged_in_user.ok_or(Error::NotLoggedIn)?; let character = conn .load_character(character_id) .await? .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)) }