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 serde::Serialize; mod edit; 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::edit_character_page ] } #[derive(Serialize)] struct ViewCharacterContext<'a> { pub id: i32, 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 = ViewCharacterContext { id: character.id, name: &character.character_name, username: &user.username, data_type: &character.data_type, sheet: character.dyn_deserialize()?, }; let template = if character.data_type.is_cofd_system() { Template::render("characters/view_character", context) } else { return Err(Error::InvalidInput); }; 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) }