tenebrous-sheets/src/routes/api/cofd.rs

223 lines
6.6 KiB
Rust

use super::load_character;
use crate::db::{Dao, TenebrousDbConn};
use crate::errors::Error;
use crate::models::characters::Character;
use crate::models::proto::cofd::api::DefaultCharacterIdentifier;
use crate::models::proto::cofd::cofd_sheet::Skill;
use crate::models::proto::cofd::*;
use crate::models::proto::{cofd::api::*, cofd::*, Proto};
use crate::models::users::User;
use std::collections::btree_map::{Entry, OccupiedEntry};
fn find_skill_entry<'a>(
sheet: &'a mut CofdSheet,
skill_name: &'a str,
) -> Option<OccupiedEntry<'a, String, Skill>> {
let all_skills = vec![
&mut sheet.mental_skills,
&mut sheet.physical_skills,
&mut sheet.social_skills,
];
// Search all skill lists for this value using "workaround" to
// break value from for loops.
let skill: Option<OccupiedEntry<_, _>> = 'l: loop {
for skill_map in all_skills {
if let Entry::Occupied(entry) = skill_map.entry(skill_name.to_owned()) {
break 'l Some(entry);
}
}
break None;
};
skill
}
fn find_skill<'a>(sheet: &'a mut CofdSheet, skill_name: &'a str) -> Option<&'a mut Skill> {
find_skill_entry(sheet, skill_name).map(|entry| entry.into_mut())
}
#[post("/rpc/cofd/update_basic_info", data = "<req>")]
pub(super) async fn update_basic_info<'a>(
req: Proto<UpdateBasicInfoRequest>,
conn: TenebrousDbConn<'_>,
user: Option<&User>,
) -> Result<Proto<ApiResult>, Error> {
let mut character =
load_character(&conn, user, &req.character.owner(), req.character.id()).await?;
let mut sheet: CofdSheet = character.try_deserialize()?;
println!("name will now be {}", req.name);
character.character_name = req.name.clone(); //Should probably remove name from the sheet?
sheet.name = req.name.clone();
sheet.gender = req.gender.clone();
sheet.concept = req.concept.clone();
sheet.chronicle = req.chronicle.clone();
sheet.age = req.age;
character.update_data(&sheet)?;
conn.update_character(&character).await?;
println!("Updated basic info");
Ok(Proto(ApiResult::success()))
}
#[post("/rpc/cofd/update_attribute_value", data = "<req>")]
pub(super) async fn update_attribute_value(
req: Proto<UpdateAttributeRequest>,
conn: TenebrousDbConn<'_>,
logged_in_user: Option<&User>,
) -> Result<Proto<ApiResult>, Error> {
let mut character = load_character(
&conn,
logged_in_user,
&req.character.owner(),
req.character.id(),
)
.await?;
let mut sheet: CofdSheet = character.try_deserialize()?;
let value = req.attribute_value;
match req.attribute_name.to_lowercase().as_ref() {
"strength" => Ok(sheet.strength = value),
"dexterity" => Ok(sheet.dexterity = value),
"stamina" => Ok(sheet.stamina = value),
"intelligence" => Ok(sheet.intelligence = value),
"wits" => Ok(sheet.wits = value),
"resolve" => Ok(sheet.resolve = value),
"presence" => Ok(sheet.presence = value),
"manipulation" => Ok(sheet.manipulation = value),
"composure" => Ok(sheet.composure = value),
_ => Err(Error::InvalidInput),
}?;
character.update_data(&sheet)?;
conn.update_character_sheet(&character).await?;
Ok(Proto(ApiResult {
success: true,
error: "".to_string(),
}))
}
#[patch("/rpc/cofd/update_skill", data = "<skill_update>")]
pub(super) async fn update_skill<'a>(
skill_update: Proto<UpdateSkillRequest>,
conn: TenebrousDbConn<'_>,
logged_in_user: Option<&User>,
) -> Result<&'a str, Error> {
let mut character = load_character(
&conn,
logged_in_user,
&skill_update.character.owner(),
skill_update.character.id(),
)
.await?;
let mut sheet: CofdSheet = character.try_deserialize()?;
let updated_skill: &Skill = skill_update.skill.as_ref().ok_or(Error::InvalidInput)?;
let skill_entry = find_skill_entry(&mut sheet, &updated_skill.name);
skill_entry
.map(|mut entry| entry.insert(updated_skill.clone()))
.ok_or(Error::InvalidInput)?;
println!(
"updated skill {} with {:?}",
updated_skill.name, skill_update.skill
);
character.update_data(&sheet)?;
conn.update_character_sheet(&character).await?;
Ok("lol")
}
#[post("/rpc/cofd/update_skill_value", data = "<req>")]
pub(super) async fn update_skill_value<'a>(
req: Proto<UpdateSkillValueRequest>,
conn: TenebrousDbConn<'_>,
logged_in_user: Option<&User>,
) -> Result<Proto<ApiResult>, Error> {
let mut character = load_character(
&conn,
logged_in_user,
&req.character.owner(),
req.character.id(),
)
.await?;
let mut sheet: CofdSheet = character.try_deserialize()?;
let mut skill: Option<&mut Skill> = find_skill(&mut sheet, &req.skill_name);
if let Some(ref mut s) = skill {
s.dots = req.skill_value;
}
println!("updated skill value");
character.update_data(&sheet)?;
conn.update_character_sheet(&character).await?;
Ok(Proto(ApiResult {
success: true,
error: "".to_string(),
}))
}
#[post("/rpc/cofd/update_merits", data = "<req>")]
pub(super) async fn update_merits<'a>(
req: Proto<UpdateMeritsRequest>,
conn: TenebrousDbConn<'_>,
logged_in_user: Option<&User>,
) -> Result<Proto<ApiResult>, Error> {
let mut character = load_character(
&conn,
logged_in_user,
&req.character.owner(),
req.character.id(),
)
.await?;
let mut sheet: CofdSheet = character.try_deserialize()?;
sheet.merits = req.merits.clone();
println!("updated merits");
character.update_data(&sheet)?;
conn.update_character_sheet(&character).await?;
Ok(Proto(ApiResult::success()))
}
#[post("/rpc/cofd/update_items", data = "<req>")]
pub(super) async fn update_items<'a>(
req: Proto<UpdateItemsRequest>,
conn: TenebrousDbConn<'_>,
logged_in_user: Option<&User>,
) -> Result<Proto<ApiResult>, Error> {
let mut character = load_character(
&conn,
logged_in_user,
&req.character.owner(),
req.character.id(),
)
.await?;
let mut sheet: CofdSheet = character.try_deserialize()?;
sheet.items = req.items.clone();
println!("updated items");
character.update_data(&sheet)?;
conn.update_character_sheet(&character).await?;
Ok(Proto(ApiResult::success()))
}
#[put("/rpc/cofd/add_condition", data = "<info>")]
pub(super) fn add_condition<'a>(info: Proto<AddConditionRequest>) -> &'a str {
"lol"
}
#[delete("/rpc/cofd/remove_condition", data = "<info>")]
pub(super) fn remove_condition<'a>(info: Proto<RemoveConditionRequest>) -> &'a str {
"lol"
}