tenebrous-sheets/src/routes/characters.rs

119 lines
3.4 KiB
Rust
Raw Normal View History

use crate::db::{Dao, TenebrousDbConn};
2020-12-01 21:32:16 +00:00
use crate::errors::Error;
use crate::models::characters::{CharacterDataType, DynCharacterData, Visibility};
use crate::models::users::User;
use rocket::request::Form;
use rocket::response::Redirect;
2020-12-01 21:32:16 +00:00
use rocket_contrib::templates::Template;
use serde::Serialize;
2020-12-01 21:32:16 +00:00
use std::collections::HashMap;
pub(crate) fn routes() -> Vec<rocket::Route> {
routes![
view_character,
new_character,
create_new_character,
new_character_not_logged_in,
edit_character
]
2020-12-01 21:32:16 +00:00
}
#[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<DynCharacterData>,
}
#[get("/<username>/<character_id>")]
2020-12-01 21:32:16 +00:00
fn view_character(
character_id: i32,
username: String,
2020-12-01 21:32:16 +00:00
conn: TenebrousDbConn,
logged_in_user: Option<&User>,
2020-12-01 21:32:16 +00:00
) -> Result<Template, Error> {
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)?;
2020-12-01 21:32:16 +00:00
let context = ViewCharacterTemplate {
name: &character.character_name,
username: &user.username,
sheet: character.dyn_deserialize()?,
};
2020-12-01 21:32:16 +00:00
Ok(Template::render("view_character", context))
}
#[get("/new")]
fn new_character(logged_in_user: &User, conn: TenebrousDbConn) -> Result<Template, Error> {
let context = HashMap::<String, String>::new();
Ok(Template::render("new_character", context))
}
#[post("/new", data = "<form>")]
fn create_new_character(
form: Form<NewCharacterForm>,
logged_in_user: &User,
conn: TenebrousDbConn,
) -> Result<Redirect, Error> {
//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()
}
2020-12-01 21:32:16 +00:00
#[get("/<owner>/<character_id>/edit")]
fn edit_character(
character_id: i32,
owner: String,
logged_in_user: Option<&User>,
2020-12-01 21:32:16 +00:00
conn: TenebrousDbConn,
) -> Result<Template, Error> {
let owner = conn.load_user(&owner)?.ok_or(Error::NotFound)?;
2020-12-01 21:32:16 +00:00
let logged_in_user = logged_in_user.ok_or(Error::NotLoggedIn)?;
let character = conn.load_character(character_id)?.ok_or(Error::NotFound)?;
2020-12-01 21:32:16 +00:00
if logged_in_user != &owner {
2020-12-01 21:32:16 +00:00
return Err(Error::NoPermission);
}
let mut context = HashMap::new();
context.insert("name", character.character_name);
2020-12-01 21:32:16 +00:00
context.insert("username", owner.username);
Ok(Template::render("view_character", context))
}