Updated query parameters for spells

This commit is contained in:
Benjamin Sherriff
2023-10-04 13:09:04 -04:00
parent 4d3e8ae981
commit 8da46fdd5e
8 changed files with 422 additions and 199 deletions

View File

@@ -6,7 +6,7 @@
"ritual": false, "ritual": false,
"casting_time": { "casting_time": {
"amount": 1, "amount": 1,
"type": "action" "unit": "action"
}, },
"range": { "range": {
"type": "point", "type": "point",
@@ -49,7 +49,7 @@
"ritual": false, "ritual": false,
"casting_time": { "casting_time": {
"amount": 1, "amount": 1,
"type": "action" "unit": "action"
}, },
"range": { "range": {
"type": "self" "type": "self"
@@ -88,7 +88,7 @@
"ritual": false, "ritual": false,
"casting_time": { "casting_time": {
"amount": 1, "amount": 1,
"type": "action" "unit": "action"
}, },
"range": { "range": {
"type": "touch" "type": "touch"
@@ -134,7 +134,7 @@
"ritual": false, "ritual": false,
"casting_time": { "casting_time": {
"amount": 1, "amount": 1,
"type": "action" "unit": "action"
}, },
"range": { "range": {
"type": "point", "type": "point",
@@ -177,7 +177,7 @@
"ritual": false, "ritual": false,
"casting_time": { "casting_time": {
"amount": 1, "amount": 1,
"type": "action" "unit": "action"
}, },
"range": { "range": {
"type": "point", "type": "point",
@@ -232,7 +232,7 @@
"ritual": false, "ritual": false,
"casting_time": { "casting_time": {
"amount": 1, "amount": 1,
"type": "action" "unit": "action"
}, },
"range": { "range": {
"type": "point", "type": "point",
@@ -276,7 +276,7 @@
"ritual": false, "ritual": false,
"casting_time": { "casting_time": {
"amount": 1, "amount": 1,
"type": "action" "unit": "action"
}, },
"range": { "range": {
"type": "point", "type": "point",
@@ -315,7 +315,7 @@
"ritual": false, "ritual": false,
"casting_time": { "casting_time": {
"amount": 1, "amount": 1,
"type": "action" "unit": "action"
}, },
"range": { "range": {
"type": "point", "type": "point",
@@ -359,7 +359,7 @@
"ritual": false, "ritual": false,
"casting_time": { "casting_time": {
"amount": 1, "amount": 1,
"type": "action" "unit": "action"
}, },
"range": { "range": {
"type": "point", "type": "point",
@@ -391,5 +391,41 @@
"The spell creates more than one beam when you reach higher levels: two beams at 5th level, three beams at 11th level, and four beams at 17th level. You can direct the beams at the same target or at different ones. Make a separate attack roll for each beam." "The spell creates more than one beam when you reach higher levels: two beams at 5th level, three beams at 11th level, and four beams at 17th level. You can direct the beams at the same target or at different ones. Make a separate attack roll for each beam."
] ]
} }
},
{
"name": "Encode Thoughts",
"school": "enchantment",
"level": 0,
"ritual": true,
"casting_time": {
"amount": 1,
"unit": "action"
},
"range": {
"type": "self"
},
"components": {
"verbal": false,
"somatic": true,
"material": false
},
"durations": [
{
"type": "timed",
"amount": 8,
"unit": "hours"
}
],
"classes": ["wizard"],
"sources": [
{ "source": "GGR", "page": 47 }
],
"description": {
"entries": [
"Putting a finger to your head, you pull a memory, an idea, or a message from your mind and transform it into a tangible string of glowing energy called a thought strand, which persists for the duration or until you cast this spell again. The thought strand appears in an unoccupied space within 5 feet of you as a Tiny, weightless, semisolid object that can be held and carried like a ribbon. It is otherwise stationary.",
"If you cast this spell while concentrating on a spell or an ability that allows you to read or manipulate the thoughts of others (such as {@spell detect thoughts} or {@spell modify memory}), you can transform the thoughts or memories you read, rather than your own, into a thought strand.",
"Casting this spell while holding a thought strand allows you to instantly receive whatever memory, idea, or message the thought strand contains. (Casting {@spell detect thoughts} on the strand has the same effect.)"
]
}
} }
] ]

View File

@@ -1,5 +1,15 @@
CREATE TABLE IF NOT EXISTS spells ( CREATE TABLE IF NOT EXISTS spells (
id INTEGER GENERATED ALWAYS AS IDENTITY, id INTEGER GENERATED ALWAYS AS IDENTITY,
name TEXT NOT NULL, name TEXT NOT NULL,
school TEXT NOT NULL,
level INTEGER NOT NULL,
ritual BOOLEAN DEFAULT FALSE,
concentration BOOLEAN DEFAULT FALSE,
classes TEXT[] NOT NULL,
damage_inflict TEXT[] NOT NULL,
damage_resist TEXT[] NOT NULL,
conditions TEXT[] NOT NULL,
saving_throw TEXT[] NOT NULL,
attack_type TEXT,
data JSONB NOT NULL data JSONB NOT NULL
); );

View File

@@ -1,4 +1,4 @@
// use std::str::FromStr; use std::str::FromStr;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@@ -17,30 +17,30 @@ pub enum AbilityType {
Charisma Charisma
} }
// impl AbilityType { impl AbilityType {
// pub fn to_string(&self) -> String { pub fn to_string(&self) -> String {
// match self { match self {
// AbilityType::Strength => "Strength".to_string(), AbilityType::Strength => "Strength".to_string(),
// AbilityType::Dexterity => "Dexterity".to_string(), AbilityType::Dexterity => "Dexterity".to_string(),
// AbilityType::Constitution => "Constitution".to_string(), AbilityType::Constitution => "Constitution".to_string(),
// AbilityType::Intelligence => "Intelligence".to_string(), AbilityType::Intelligence => "Intelligence".to_string(),
// AbilityType::Wisdom => "Wisdom".to_string(), AbilityType::Wisdom => "Wisdom".to_string(),
// AbilityType::Charisma => "Charisma".to_string() AbilityType::Charisma => "Charisma".to_string()
// } }
// } }
// } }
// impl FromStr for AbilityType { impl FromStr for AbilityType {
// type Err = (); type Err = ();
// fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
// match s { match s {
// "Strength" => Ok(AbilityType::Strength), "Strength" => Ok(AbilityType::Strength),
// "Dexterity" => Ok(AbilityType::Dexterity), "Dexterity" => Ok(AbilityType::Dexterity),
// "Constitution" => Ok(AbilityType::Constitution), "Constitution" => Ok(AbilityType::Constitution),
// "Intelligence" => Ok(AbilityType::Intelligence), "Intelligence" => Ok(AbilityType::Intelligence),
// "Wisdom" => Ok(AbilityType::Wisdom), "Wisdom" => Ok(AbilityType::Wisdom),
// "Charisma" => Ok(AbilityType::Charisma), "Charisma" => Ok(AbilityType::Charisma),
// _ => Err(()) _ => Err(())
// } }
// } }
// } }

View File

@@ -1,4 +1,4 @@
// use std::str::FromStr; use std::str::FromStr;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@@ -36,48 +36,48 @@ pub enum ConditionType {
Unconscious Unconscious
} }
// impl ConditionType { impl ConditionType {
// pub fn to_string(&self) -> String { pub fn to_string(&self) -> String {
// match self { match self {
// ConditionType::Blinded => "Blinded".to_string(), ConditionType::Blinded => "Blinded".to_string(),
// ConditionType::Charmed => "Charmed".to_string(), ConditionType::Charmed => "Charmed".to_string(),
// ConditionType::Deafened => "Deafened".to_string(), ConditionType::Deafened => "Deafened".to_string(),
// ConditionType::Exhaustion => "Exhaustion".to_string(), ConditionType::Exhaustion => "Exhaustion".to_string(),
// ConditionType::Frightened => "Frightened".to_string(), ConditionType::Frightened => "Frightened".to_string(),
// ConditionType::Grappled => "Grappled".to_string(), ConditionType::Grappled => "Grappled".to_string(),
// ConditionType::Incapacitated => "Incapacitated".to_string(), ConditionType::Incapacitated => "Incapacitated".to_string(),
// ConditionType::Invisible => "Invisible".to_string(), ConditionType::Invisible => "Invisible".to_string(),
// ConditionType::Paralyzed => "Paralyzed".to_string(), ConditionType::Paralyzed => "Paralyzed".to_string(),
// ConditionType::Petrified => "Petrified".to_string(), ConditionType::Petrified => "Petrified".to_string(),
// ConditionType::Poisoned => "Poisoned".to_string(), ConditionType::Poisoned => "Poisoned".to_string(),
// ConditionType::Prone => "Prone".to_string(), ConditionType::Prone => "Prone".to_string(),
// ConditionType::Restrained => "Restrained".to_string(), ConditionType::Restrained => "Restrained".to_string(),
// ConditionType::Stunned => "Stunned".to_string(), ConditionType::Stunned => "Stunned".to_string(),
// ConditionType::Unconscious => "Unconscious".to_string() ConditionType::Unconscious => "Unconscious".to_string()
// } }
// } }
// } }
// impl FromStr for ConditionType { impl FromStr for ConditionType {
// type Err = (); type Err = ();
// fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
// match s { match s {
// "Blinded" => Ok(ConditionType::Blinded), "Blinded" => Ok(ConditionType::Blinded),
// "Charmed" => Ok(ConditionType::Charmed), "Charmed" => Ok(ConditionType::Charmed),
// "Deafened" => Ok(ConditionType::Deafened), "Deafened" => Ok(ConditionType::Deafened),
// "Exhaustion" => Ok(ConditionType::Exhaustion), "Exhaustion" => Ok(ConditionType::Exhaustion),
// "Frightened" => Ok(ConditionType::Frightened), "Frightened" => Ok(ConditionType::Frightened),
// "Grappled" => Ok(ConditionType::Grappled), "Grappled" => Ok(ConditionType::Grappled),
// "Incapacitated" => Ok(ConditionType::Incapacitated), "Incapacitated" => Ok(ConditionType::Incapacitated),
// "Invisible" => Ok(ConditionType::Invisible), "Invisible" => Ok(ConditionType::Invisible),
// "Paralyzed" => Ok(ConditionType::Paralyzed), "Paralyzed" => Ok(ConditionType::Paralyzed),
// "Petrified" => Ok(ConditionType::Petrified), "Petrified" => Ok(ConditionType::Petrified),
// "Poisoned" => Ok(ConditionType::Poisoned), "Poisoned" => Ok(ConditionType::Poisoned),
// "Prone" => Ok(ConditionType::Prone), "Prone" => Ok(ConditionType::Prone),
// "Restrained" => Ok(ConditionType::Restrained), "Restrained" => Ok(ConditionType::Restrained),
// "Stunned" => Ok(ConditionType::Stunned), "Stunned" => Ok(ConditionType::Stunned),
// "Unconscious" => Ok(ConditionType::Unconscious), "Unconscious" => Ok(ConditionType::Unconscious),
// _ => Err(()) _ => Err(())
// } }
// } }
// } }

View File

@@ -17,6 +17,16 @@ diesel::table! {
spells (id) { spells (id) {
id -> Integer, id -> Integer,
name -> Text, name -> Text,
school -> Text,
level -> Integer,
ritual -> Bool,
concentration -> Bool,
classes -> Array<Text>,
damage_inflict -> Array<Text>,
damage_resist -> Array<Text>,
conditions -> Array<Text>,
saving_throw -> Array<Text>,
attack_type -> Nullable<Text>,
data -> Jsonb data -> Jsonb
} }
} }

View File

@@ -3,29 +3,39 @@ use serde::{Deserialize, Serialize};
use crate::{db::{schema::spells::{self}, classes::AbilityType, conditions::ConditionType}, error_handler::ServiceError}; use crate::{db::{schema::spells::{self}, classes::AbilityType, conditions::ConditionType}, error_handler::ServiceError};
use super::{SchoolType, CastingTime, CastingType, SpellAttackType, SpellDamageType, Range, Area, Components, Duration, Source, Description}; use super::{SchoolType, CastingTime, CastingType, SpellAttackType, SpellDamageType, Range, Area, Components, Duration, Source, Description, DurationType};
#[derive(Queryable, QueryableByName)] #[derive(Queryable, QueryableByName)]
#[diesel(table_name = spells)] #[diesel(table_name = spells)]
pub struct QuerySpell { pub struct QuerySpell {
pub id: i32, pub id: i32,
pub name: String, pub name: String,
pub school: String,
pub level: i32,
pub ritual: bool,
pub concentration: bool,
pub classes: Vec<String>,
pub damage_inflict: Vec<String>,
pub damage_resist: Vec<String>,
pub conditions: Vec<String>,
pub saving_throw: Vec<String>,
pub attack_type: Option<String>,
pub data: serde_json::Value, pub data: serde_json::Value,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct QueryFilters { pub struct QueryFilters {
pub by_name: Option<String>, pub by_name: Option<String>,
pub by_schools: Option<Vec<SchoolType>>, pub by_schools: Option<Vec<String>>,
pub by_levels: Option<Vec<i32>>, pub by_levels: Option<Vec<i32>>,
pub by_ritual: Option<bool>, pub by_ritual: Option<bool>,
pub by_concentration: Option<bool>, pub by_concentration: Option<bool>,
pub by_classes: Option<Vec<String>>, pub by_classes: Option<Vec<String>>,
pub by_damage_inflict: Option<Vec<SpellDamageType>>, pub by_damage_inflict: Option<Vec<String>>,
pub by_damage_resist: Option<Vec<SpellDamageType>>, pub by_damage_resist: Option<Vec<String>>,
pub by_conditions: Option<Vec<ConditionType>>, pub by_conditions: Option<Vec<String>>,
pub by_saving_throw: Option<Vec<AbilityType>>, pub by_saving_throw: Option<Vec<String>>,
pub by_attack_type: Option<SpellAttackType>, pub by_attack_type: Option<String>,
} }
impl Default for QueryFilters { impl Default for QueryFilters {
@@ -53,15 +63,85 @@ impl QuerySpell {
// Limit query to page and limit // Limit query to page and limit
let offset = (page - 1) * limit; let offset = (page - 1) * limit;
query = query.offset(offset as i64); query = query.offset(offset as i64);
// Apply filters if let Some(name) = &filters.by_name {
if let Some(name) = filters.by_name.to_owned() {
query = query.filter(spells::name.ilike(format!("%{}%", name))); query = query.filter(spells::name.ilike(format!("%{}%", name)));
} }
if let Some(schools) = &filters.by_schools {
query = query.filter(spells::school.eq_any(schools.iter().map(|school| school.to_string()).collect::<Vec<String>>()));
}
if let Some(levels) = &filters.by_levels {
query = query.filter(spells::level.eq_any(levels));
}
if let Some(ritual) = filters.by_ritual {
query = query.filter(spells::ritual.eq(ritual));
}
if let Some(concentration) = filters.by_concentration {
query = query.filter(spells::concentration.eq(concentration));
}
if let Some(classes) = &filters.by_classes {
query = query.filter(spells::classes.overlaps_with(classes));
}
if let Some(damage_inflict) = &filters.by_damage_inflict {
query = query.filter(spells::damage_inflict.overlaps_with(damage_inflict.iter().map(|damage_inflict| damage_inflict.to_string()).collect::<Vec<String>>()));
}
if let Some(damage_resist) = &filters.by_damage_resist {
query = query.filter(spells::damage_resist.overlaps_with(damage_resist.iter().map(|damage_resist| damage_resist.to_string()).collect::<Vec<String>>()));
}
if let Some(conditions) = &filters.by_conditions {
query = query.filter(spells::conditions.overlaps_with(conditions.iter().map(|condition| condition.to_string()).collect::<Vec<String>>()));
}
if let Some(saving_throw) = &filters.by_saving_throw {
query = query.filter(spells::saving_throw.overlaps_with(saving_throw.iter().map(|saving_throw| saving_throw.to_string()).collect::<Vec<String>>()));
}
if let Some(attack_type) = &filters.by_attack_type {
query = query.filter(spells::attack_type.eq(attack_type.to_string()));
}
let spells = query.load::<QuerySpell>(&mut conn)?; let spells = query.load::<QuerySpell>(&mut conn)?;
Ok(spells) Ok(spells)
} }
pub fn get_count(filters: &QueryFilters) -> Result<i64, ServiceError> {
let mut conn = crate::db::connection()?;
let mut query = spells::table.count().into_boxed();
if let Some(name) = &filters.by_name {
query = query.filter(spells::name.ilike(format!("%{}%", name)));
}
if let Some(schools) = &filters.by_schools {
query = query.filter(spells::school.eq_any(schools.iter().map(|school| school.to_string()).collect::<Vec<String>>()));
}
if let Some(levels) = &filters.by_levels {
query = query.filter(spells::level.eq_any(levels));
}
if let Some(ritual) = filters.by_ritual {
query = query.filter(spells::ritual.eq(ritual));
}
if let Some(concentration) = filters.by_concentration {
query = query.filter(spells::concentration.eq(concentration));
}
if let Some(classes) = &filters.by_classes {
query = query.filter(spells::classes.overlaps_with(classes));
}
if let Some(damage_inflict) = &filters.by_damage_inflict {
query = query.filter(spells::damage_inflict.overlaps_with(damage_inflict.iter().map(|damage_inflict| damage_inflict.to_string()).collect::<Vec<String>>()));
}
if let Some(damage_resist) = &filters.by_damage_resist {
query = query.filter(spells::damage_resist.overlaps_with(damage_resist.iter().map(|damage_resist| damage_resist.to_string()).collect::<Vec<String>>()));
}
if let Some(conditions) = &filters.by_conditions {
query = query.filter(spells::conditions.overlaps_with(conditions.iter().map(|condition| condition.to_string()).collect::<Vec<String>>()));
}
if let Some(saving_throw) = &filters.by_saving_throw {
query = query.filter(spells::saving_throw.overlaps_with(saving_throw.iter().map(|saving_throw| saving_throw.to_string()).collect::<Vec<String>>()));
}
if let Some(attack_type) = &filters.by_attack_type {
query = query.filter(spells::attack_type.eq(attack_type.to_string()));
}
let count = query.get_result(&mut conn)?;
Ok(count)
}
pub fn get_by_id(id: i32) -> Result<Self, ServiceError> { pub fn get_by_id(id: i32) -> Result<Self, ServiceError> {
let mut conn = crate::db::connection()?; let mut conn = crate::db::connection()?;
let spell = spells::table let spell = spells::table
@@ -70,17 +150,6 @@ impl QuerySpell {
Ok(spell) Ok(spell)
} }
pub fn get_count(filters: &QueryFilters) -> Result<i64, ServiceError> {
let mut conn = crate::db::connection()?;
let mut query = spells::table.count().into_boxed();
if let Some(name) = filters.by_name.to_owned() {
query = query.filter(spells::name.ilike(format!("%{}%", name)));
}
let count = query.get_result(&mut conn)?;
Ok(count)
}
pub fn delete(id: i32) -> Result<Self, ServiceError> { pub fn delete(id: i32) -> Result<Self, ServiceError> {
let mut conn = crate::db::connection()?; let mut conn = crate::db::connection()?;
let spell = diesel::delete(spells::table.filter(spells::id.eq(id))).get_result(&mut conn)?; let spell = diesel::delete(spells::table.filter(spells::id.eq(id))).get_result(&mut conn)?;
@@ -92,6 +161,16 @@ impl QuerySpell {
#[diesel(table_name = spells)] #[diesel(table_name = spells)]
pub struct InsertSpell { pub struct InsertSpell {
pub name: String, pub name: String,
pub school: String,
pub level: i32,
pub ritual: bool,
pub concentration: bool,
pub classes: Vec<String>,
pub damage_inflict: Vec<String>,
pub damage_resist: Vec<String>,
pub conditions: Vec<String>,
pub saving_throw: Vec<String>,
pub attack_type: Option<String>,
pub data: serde_json::Value pub data: serde_json::Value
} }
@@ -174,13 +253,38 @@ impl Into<InsertSpell> for Spell {
fn into(self) -> InsertSpell { fn into(self) -> InsertSpell {
return InsertSpell { return InsertSpell {
name: self.name.to_string(), name: self.name.to_string(),
school: self.school.to_string(),
level: self.level,
ritual: self.ritual,
concentration: self.durations.iter().any(|duration| match duration.duration_type {
DurationType::Concentration => true,
_ => false
}),
classes: self.classes.iter().map(|class| class.to_string()).collect::<Vec<String>>(),
damage_inflict: match &self.damage_inflict {
Some(damage_inflict) => damage_inflict.iter().map(|damage_inflict| damage_inflict.to_string()).collect(),
None => vec![]
},
damage_resist: match &self.damage_resist {
Some(damage_resist) => damage_resist.iter().map(|damage_resist| damage_resist.to_string()).collect(),
None => vec![]
},
conditions: match &self.conditions {
Some(conditions) => conditions.iter().map(|condition| condition.to_string()).collect(),
None => vec![]
},
saving_throw: match &self.saving_throw {
Some(saving_throw) => saving_throw.iter().map(|saving_throw| saving_throw.to_string()).collect(),
None => vec![]
},
attack_type: self.attack_type.as_ref().map(|attack_type| attack_type.to_string()),
data: match serde_json::to_value(&self) { data: match serde_json::to_value(&self) {
Ok(data) => data, Ok(data) => data,
Err(err) => { Err(err) => {
log::error!("Failed to serialize spell description: {}", err); log::error!("Failed to serialize spell: {}", err);
serde_json::Value::Null serde_json::Value::Null
} }
}, }
} }
} }
} }

View File

@@ -1,4 +1,5 @@
use actix_web::{get, post, put, delete, web, HttpResponse, HttpRequest, ResponseError}; use actix_web::{get, post, put, delete, web, HttpResponse, HttpRequest, ResponseError};
use log::error;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use crate::{db::{spells::{QuerySpell, QueryFilters}, GetResponse, Metadata}, error_handler::ServiceError}; use crate::{db::{spells::{QuerySpell, QueryFilters}, GetResponse, Metadata}, error_handler::ServiceError};
@@ -8,6 +9,16 @@ use super::{Spell, InsertSpell};
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct GetAllParams { struct GetAllParams {
name: Option<String>, name: Option<String>,
schools: Option<String>,
levels: Option<String>,
ritual: Option<bool>,
concentration: Option<bool>,
classes: Option<String>,
damage_inflict: Option<String>,
damage_resist: Option<String>,
conditions: Option<String>,
saving_throw: Option<String>,
attack_type: Option<String>,
limit: Option<i32>, limit: Option<i32>,
page: Option<i32>, page: Option<i32>,
} }
@@ -23,6 +34,43 @@ async fn get_all(req: HttpRequest) -> HttpResponse {
}; };
let mut filters = QueryFilters::default(); let mut filters = QueryFilters::default();
filters.by_name = params.name.clone(); filters.by_name = params.name.clone();
filters.by_schools = match &params.schools {
Some(schools) => Some(schools.split(",").map(|s| s.to_string()).collect()),
None => None
};
filters.by_levels = match &params.levels {
Some(levels) => Some(levels.split(",").map(|s| match s.to_string().parse::<i32>() {
Ok(level) => level,
Err(_) => 0
}).collect()),
None => None
};
filters.by_ritual = params.ritual;
filters.by_concentration = params.concentration;
filters.by_classes = match &params.classes {
Some(classes) => Some(classes.split(",").map(|s| s.to_string()).collect()),
None => None
};
filters.by_damage_inflict = match &params.damage_inflict {
Some(damage_inflict) => Some(damage_inflict.split(",").map(|s| s.to_string()).collect()),
None => None
};
filters.by_damage_resist = match &params.damage_resist {
Some(damage_resist) => Some(damage_resist.split(",").map(|s| s.to_string()).collect()),
None => None
};
filters.by_conditions = match &params.conditions {
Some(conditions) => Some(conditions.split(",").map(|s| s.to_string()).collect()),
None => None
};
filters.by_saving_throw = match &params.saving_throw {
Some(saving_throw) => Some(saving_throw.split(",").map(|s| s.to_string()).collect()),
None => None
};
filters.by_attack_type = match &params.attack_type {
Some(attack_type) => Some(attack_type.split(",").map(|s| s.to_string()).collect()),
None => None
};
// Limit must be between 1 and 100 // Limit must be between 1 and 100
let limit = std::cmp::min(std::cmp::max(params.limit.unwrap_or(20), 1), 100); let limit = std::cmp::min(std::cmp::max(params.limit.unwrap_or(20), 1), 100);
let total_count = QuerySpell::get_count(&filters).unwrap(); let total_count = QuerySpell::get_count(&filters).unwrap();
@@ -46,7 +94,10 @@ async fn get_all(req: HttpRequest) -> HttpResponse {
}) })
}) })
}, },
Err(err) => ResponseError::error_response(&err) Err(err) => {
error!("{:?}", err.message);
ResponseError::error_response(&err)
}
} }
} }
@@ -64,7 +115,10 @@ async fn get_by_id(id: web::Path<String>) -> HttpResponse {
data: Spell::from(spell), data: Spell::from(spell),
metadata: None metadata: None
}), }),
Err(err) => ResponseError::error_response(&err) Err(err) => {
error!("{:?}", err.message);
ResponseError::error_response(&err)
}
} }
} }
@@ -72,7 +126,10 @@ async fn get_by_id(id: web::Path<String>) -> HttpResponse {
async fn create(spell: web::Json<Spell>) -> HttpResponse { async fn create(spell: web::Json<Spell>) -> HttpResponse {
match InsertSpell::insert(spell.into_inner().into()) { match InsertSpell::insert(spell.into_inner().into()) {
Ok(spell) => HttpResponse::Created().json(Spell::from(spell)), Ok(spell) => HttpResponse::Created().json(Spell::from(spell)),
Err(err) => ResponseError::error_response(&err) Err(err) => {
error!("{:?}", err.message);
ResponseError::error_response(&err)
}
} }
} }
@@ -87,7 +144,10 @@ async fn update(id: web::Path<String>, spell: web::Json<Spell>) -> HttpResponse
}; };
match web::block(move || InsertSpell::update(id, spell.into_inner().into())).await.unwrap() { match web::block(move || InsertSpell::update(id, spell.into_inner().into())).await.unwrap() {
Ok(spell) => HttpResponse::Ok().json(Spell::from(spell)), Ok(spell) => HttpResponse::Ok().json(Spell::from(spell)),
Err(err) => ResponseError::error_response(&err) Err(err) => {
error!("{:?}", err.message);
ResponseError::error_response(&err)
}
} }
} }
@@ -102,7 +162,10 @@ async fn delete(id: web::Path<String>) -> HttpResponse {
}; };
match web::block(move || QuerySpell::delete(id)).await.unwrap() { match web::block(move || QuerySpell::delete(id)).await.unwrap() {
Ok(spell) => HttpResponse::Ok().json(Spell::from(spell)), Ok(spell) => HttpResponse::Ok().json(Spell::from(spell)),
Err(err) => ResponseError::error_response(&err) Err(err) => {
error!("{:?}", err.message);
ResponseError::error_response(&err)
}
} }
} }

View File

@@ -1,4 +1,4 @@
// use std::str::FromStr; use std::str::FromStr;
use serde::{Deserialize, Serialize, ser::SerializeMap}; use serde::{Deserialize, Serialize, ser::SerializeMap};
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@@ -21,43 +21,43 @@ pub enum SchoolType {
Transmutation Transmutation
} }
// impl SchoolType { impl SchoolType {
// pub fn to_string(&self) -> String { pub fn to_string(&self) -> String {
// match self { match self {
// SchoolType::Abjuration => "abjuration".to_string(), SchoolType::Abjuration => "abjuration".to_string(),
// SchoolType::Conjuration => "conjuration".to_string(), SchoolType::Conjuration => "conjuration".to_string(),
// SchoolType::Divination => "divination".to_string(), SchoolType::Divination => "divination".to_string(),
// SchoolType::Enchantment => "enchantment".to_string(), SchoolType::Enchantment => "enchantment".to_string(),
// SchoolType::Evocation => "evocation".to_string(), SchoolType::Evocation => "evocation".to_string(),
// SchoolType::Illusion => "illusion".to_string(), SchoolType::Illusion => "illusion".to_string(),
// SchoolType::Necromancy => "necromancy".to_string(), SchoolType::Necromancy => "necromancy".to_string(),
// SchoolType::Transmutation => "transmutation".to_string() SchoolType::Transmutation => "transmutation".to_string()
// } }
// } }
// } }
// impl FromStr for SchoolType { impl FromStr for SchoolType {
// type Err = (); type Err = ();
// fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
// match s { match s {
// "abjuration" => Ok(SchoolType::Abjuration), "abjuration" => Ok(SchoolType::Abjuration),
// "conjuration" => Ok(SchoolType::Conjuration), "conjuration" => Ok(SchoolType::Conjuration),
// "divination" => Ok(SchoolType::Divination), "divination" => Ok(SchoolType::Divination),
// "enchantment" => Ok(SchoolType::Enchantment), "enchantment" => Ok(SchoolType::Enchantment),
// "evocation" => Ok(SchoolType::Evocation), "evocation" => Ok(SchoolType::Evocation),
// "illusion" => Ok(SchoolType::Illusion), "illusion" => Ok(SchoolType::Illusion),
// "necromancy" => Ok(SchoolType::Necromancy), "necromancy" => Ok(SchoolType::Necromancy),
// "transmutation" => Ok(SchoolType::Transmutation), "transmutation" => Ok(SchoolType::Transmutation),
// _ => Err(()) _ => Err(())
// } }
// } }
// } }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct CastingTime { pub struct CastingTime {
pub amount: i32, pub amount: i32,
#[serde(rename = "type")] #[serde(rename = "unit")]
pub casting_type: CastingType pub casting_type: CastingType
} }
@@ -110,26 +110,26 @@ pub enum SpellAttackType {
Ranged, Ranged,
} }
// impl SpellAttackType { impl SpellAttackType {
// pub fn to_string(&self) -> String { pub fn to_string(&self) -> String {
// match self { match self {
// SpellAttackType::Melee => "melee".to_string(), SpellAttackType::Melee => "melee".to_string(),
// SpellAttackType::Ranged => "ranged".to_string() SpellAttackType::Ranged => "ranged".to_string()
// } }
// } }
// } }
// impl FromStr for SpellAttackType { impl FromStr for SpellAttackType {
// type Err = (); type Err = ();
// fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
// match s { match s {
// "melee" => Ok(SpellAttackType::Melee), "melee" => Ok(SpellAttackType::Melee),
// "ranged" => Ok(SpellAttackType::Ranged), "ranged" => Ok(SpellAttackType::Ranged),
// _ => Err(()) _ => Err(())
// } }
// } }
// } }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub enum SpellDamageType { pub enum SpellDamageType {
@@ -161,48 +161,48 @@ pub enum SpellDamageType {
Thunder Thunder
} }
// impl SpellDamageType { impl SpellDamageType {
// pub fn to_string(&self) -> String { pub fn to_string(&self) -> String {
// match self { match self {
// SpellDamageType::Acid => "acid".to_string(), SpellDamageType::Acid => "acid".to_string(),
// SpellDamageType::Bludgeoning => "bludgeoning".to_string(), SpellDamageType::Bludgeoning => "bludgeoning".to_string(),
// SpellDamageType::Cold => "cold".to_string(), SpellDamageType::Cold => "cold".to_string(),
// SpellDamageType::Fire => "fire".to_string(), SpellDamageType::Fire => "fire".to_string(),
// SpellDamageType::Force => "force".to_string(), SpellDamageType::Force => "force".to_string(),
// SpellDamageType::Lightning => "lightning".to_string(), SpellDamageType::Lightning => "lightning".to_string(),
// SpellDamageType::Necrotic => "necrotic".to_string(), SpellDamageType::Necrotic => "necrotic".to_string(),
// SpellDamageType::Piercing => "piercing".to_string(), SpellDamageType::Piercing => "piercing".to_string(),
// SpellDamageType::Poison => "poison".to_string(), SpellDamageType::Poison => "poison".to_string(),
// SpellDamageType::Psychic => "psychic".to_string(), SpellDamageType::Psychic => "psychic".to_string(),
// SpellDamageType::Radiant => "radiant".to_string(), SpellDamageType::Radiant => "radiant".to_string(),
// SpellDamageType::Slashing => "slashing".to_string(), SpellDamageType::Slashing => "slashing".to_string(),
// SpellDamageType::Thunder => "thunder".to_string() SpellDamageType::Thunder => "thunder".to_string()
// } }
// } }
// } }
// impl FromStr for SpellDamageType { impl FromStr for SpellDamageType {
// type Err = (); type Err = ();
// fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
// match s { match s {
// "acid" => Ok(SpellDamageType::Acid), "acid" => Ok(SpellDamageType::Acid),
// "bludgeoning" => Ok(SpellDamageType::Bludgeoning), "bludgeoning" => Ok(SpellDamageType::Bludgeoning),
// "cold" => Ok(SpellDamageType::Cold), "cold" => Ok(SpellDamageType::Cold),
// "fire" => Ok(SpellDamageType::Fire), "fire" => Ok(SpellDamageType::Fire),
// "force" => Ok(SpellDamageType::Force), "force" => Ok(SpellDamageType::Force),
// "lightning" => Ok(SpellDamageType::Lightning), "lightning" => Ok(SpellDamageType::Lightning),
// "necrotic" => Ok(SpellDamageType::Necrotic), "necrotic" => Ok(SpellDamageType::Necrotic),
// "piercing" => Ok(SpellDamageType::Piercing), "piercing" => Ok(SpellDamageType::Piercing),
// "poison" => Ok(SpellDamageType::Poison), "poison" => Ok(SpellDamageType::Poison),
// "psychic" => Ok(SpellDamageType::Psychic), "psychic" => Ok(SpellDamageType::Psychic),
// "radiant" => Ok(SpellDamageType::Radiant), "radiant" => Ok(SpellDamageType::Radiant),
// "slashing" => Ok(SpellDamageType::Slashing), "slashing" => Ok(SpellDamageType::Slashing),
// "thunder" => Ok(SpellDamageType::Thunder), "thunder" => Ok(SpellDamageType::Thunder),
// _ => Err(()) _ => Err(())
// } }
// } }
// } }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Range { pub struct Range {