From 8da46fdd5ec4390bb5766083783b08fe4d736f96 Mon Sep 17 00:00:00 2001 From: Benjamin Sherriff Date: Wed, 4 Oct 2023 13:09:04 -0400 Subject: [PATCH] Updated query parameters for spells --- data/spells/cantrips.json | 54 ++++++-- migrations/000007_create_spells/up.sql | 10 ++ src/db/classes/model.rs | 54 ++++---- src/db/conditions/mod.rs | 90 ++++++------- src/db/schema.rs | 10 ++ src/db/spells/model.rs | 150 +++++++++++++++++---- src/db/spells/routes.rs | 73 +++++++++- src/db/spells/types.rs | 180 ++++++++++++------------- 8 files changed, 422 insertions(+), 199 deletions(-) diff --git a/data/spells/cantrips.json b/data/spells/cantrips.json index 908160a..d1abdd3 100644 --- a/data/spells/cantrips.json +++ b/data/spells/cantrips.json @@ -6,7 +6,7 @@ "ritual": false, "casting_time": { "amount": 1, - "type": "action" + "unit": "action" }, "range": { "type": "point", @@ -49,7 +49,7 @@ "ritual": false, "casting_time": { "amount": 1, - "type": "action" + "unit": "action" }, "range": { "type": "self" @@ -88,7 +88,7 @@ "ritual": false, "casting_time": { "amount": 1, - "type": "action" + "unit": "action" }, "range": { "type": "touch" @@ -134,7 +134,7 @@ "ritual": false, "casting_time": { "amount": 1, - "type": "action" + "unit": "action" }, "range": { "type": "point", @@ -177,7 +177,7 @@ "ritual": false, "casting_time": { "amount": 1, - "type": "action" + "unit": "action" }, "range": { "type": "point", @@ -232,7 +232,7 @@ "ritual": false, "casting_time": { "amount": 1, - "type": "action" + "unit": "action" }, "range": { "type": "point", @@ -276,7 +276,7 @@ "ritual": false, "casting_time": { "amount": 1, - "type": "action" + "unit": "action" }, "range": { "type": "point", @@ -315,7 +315,7 @@ "ritual": false, "casting_time": { "amount": 1, - "type": "action" + "unit": "action" }, "range": { "type": "point", @@ -359,7 +359,7 @@ "ritual": false, "casting_time": { "amount": 1, - "type": "action" + "unit": "action" }, "range": { "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." ] } + }, + { + "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.)" + ] + } } ] \ No newline at end of file diff --git a/migrations/000007_create_spells/up.sql b/migrations/000007_create_spells/up.sql index 8dc9f9e..0997c05 100644 --- a/migrations/000007_create_spells/up.sql +++ b/migrations/000007_create_spells/up.sql @@ -1,5 +1,15 @@ CREATE TABLE IF NOT EXISTS spells ( id INTEGER GENERATED ALWAYS AS IDENTITY, 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 ); \ No newline at end of file diff --git a/src/db/classes/model.rs b/src/db/classes/model.rs index 9dbece8..7a42411 100644 --- a/src/db/classes/model.rs +++ b/src/db/classes/model.rs @@ -1,4 +1,4 @@ -// use std::str::FromStr; +use std::str::FromStr; use serde::{Serialize, Deserialize}; #[derive(Debug, Serialize, Deserialize)] @@ -17,30 +17,30 @@ pub enum AbilityType { Charisma } -// impl AbilityType { -// pub fn to_string(&self) -> String { -// match self { -// AbilityType::Strength => "Strength".to_string(), -// AbilityType::Dexterity => "Dexterity".to_string(), -// AbilityType::Constitution => "Constitution".to_string(), -// AbilityType::Intelligence => "Intelligence".to_string(), -// AbilityType::Wisdom => "Wisdom".to_string(), -// AbilityType::Charisma => "Charisma".to_string() -// } -// } -// } +impl AbilityType { + pub fn to_string(&self) -> String { + match self { + AbilityType::Strength => "Strength".to_string(), + AbilityType::Dexterity => "Dexterity".to_string(), + AbilityType::Constitution => "Constitution".to_string(), + AbilityType::Intelligence => "Intelligence".to_string(), + AbilityType::Wisdom => "Wisdom".to_string(), + AbilityType::Charisma => "Charisma".to_string() + } + } +} -// impl FromStr for AbilityType { -// type Err = (); -// fn from_str(s: &str) -> Result { -// match s { -// "Strength" => Ok(AbilityType::Strength), -// "Dexterity" => Ok(AbilityType::Dexterity), -// "Constitution" => Ok(AbilityType::Constitution), -// "Intelligence" => Ok(AbilityType::Intelligence), -// "Wisdom" => Ok(AbilityType::Wisdom), -// "Charisma" => Ok(AbilityType::Charisma), -// _ => Err(()) -// } -// } -// } \ No newline at end of file +impl FromStr for AbilityType { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "Strength" => Ok(AbilityType::Strength), + "Dexterity" => Ok(AbilityType::Dexterity), + "Constitution" => Ok(AbilityType::Constitution), + "Intelligence" => Ok(AbilityType::Intelligence), + "Wisdom" => Ok(AbilityType::Wisdom), + "Charisma" => Ok(AbilityType::Charisma), + _ => Err(()) + } + } +} \ No newline at end of file diff --git a/src/db/conditions/mod.rs b/src/db/conditions/mod.rs index 01a9b2e..e281d3e 100644 --- a/src/db/conditions/mod.rs +++ b/src/db/conditions/mod.rs @@ -1,4 +1,4 @@ -// use std::str::FromStr; +use std::str::FromStr; use serde::{Deserialize, Serialize}; @@ -36,48 +36,48 @@ pub enum ConditionType { Unconscious } -// impl ConditionType { -// pub fn to_string(&self) -> String { -// match self { -// ConditionType::Blinded => "Blinded".to_string(), -// ConditionType::Charmed => "Charmed".to_string(), -// ConditionType::Deafened => "Deafened".to_string(), -// ConditionType::Exhaustion => "Exhaustion".to_string(), -// ConditionType::Frightened => "Frightened".to_string(), -// ConditionType::Grappled => "Grappled".to_string(), -// ConditionType::Incapacitated => "Incapacitated".to_string(), -// ConditionType::Invisible => "Invisible".to_string(), -// ConditionType::Paralyzed => "Paralyzed".to_string(), -// ConditionType::Petrified => "Petrified".to_string(), -// ConditionType::Poisoned => "Poisoned".to_string(), -// ConditionType::Prone => "Prone".to_string(), -// ConditionType::Restrained => "Restrained".to_string(), -// ConditionType::Stunned => "Stunned".to_string(), -// ConditionType::Unconscious => "Unconscious".to_string() -// } -// } -// } +impl ConditionType { + pub fn to_string(&self) -> String { + match self { + ConditionType::Blinded => "Blinded".to_string(), + ConditionType::Charmed => "Charmed".to_string(), + ConditionType::Deafened => "Deafened".to_string(), + ConditionType::Exhaustion => "Exhaustion".to_string(), + ConditionType::Frightened => "Frightened".to_string(), + ConditionType::Grappled => "Grappled".to_string(), + ConditionType::Incapacitated => "Incapacitated".to_string(), + ConditionType::Invisible => "Invisible".to_string(), + ConditionType::Paralyzed => "Paralyzed".to_string(), + ConditionType::Petrified => "Petrified".to_string(), + ConditionType::Poisoned => "Poisoned".to_string(), + ConditionType::Prone => "Prone".to_string(), + ConditionType::Restrained => "Restrained".to_string(), + ConditionType::Stunned => "Stunned".to_string(), + ConditionType::Unconscious => "Unconscious".to_string() + } + } +} -// impl FromStr for ConditionType { -// type Err = (); -// fn from_str(s: &str) -> Result { -// match s { -// "Blinded" => Ok(ConditionType::Blinded), -// "Charmed" => Ok(ConditionType::Charmed), -// "Deafened" => Ok(ConditionType::Deafened), -// "Exhaustion" => Ok(ConditionType::Exhaustion), -// "Frightened" => Ok(ConditionType::Frightened), -// "Grappled" => Ok(ConditionType::Grappled), -// "Incapacitated" => Ok(ConditionType::Incapacitated), -// "Invisible" => Ok(ConditionType::Invisible), -// "Paralyzed" => Ok(ConditionType::Paralyzed), -// "Petrified" => Ok(ConditionType::Petrified), -// "Poisoned" => Ok(ConditionType::Poisoned), -// "Prone" => Ok(ConditionType::Prone), -// "Restrained" => Ok(ConditionType::Restrained), -// "Stunned" => Ok(ConditionType::Stunned), -// "Unconscious" => Ok(ConditionType::Unconscious), -// _ => Err(()) -// } -// } -// } +impl FromStr for ConditionType { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "Blinded" => Ok(ConditionType::Blinded), + "Charmed" => Ok(ConditionType::Charmed), + "Deafened" => Ok(ConditionType::Deafened), + "Exhaustion" => Ok(ConditionType::Exhaustion), + "Frightened" => Ok(ConditionType::Frightened), + "Grappled" => Ok(ConditionType::Grappled), + "Incapacitated" => Ok(ConditionType::Incapacitated), + "Invisible" => Ok(ConditionType::Invisible), + "Paralyzed" => Ok(ConditionType::Paralyzed), + "Petrified" => Ok(ConditionType::Petrified), + "Poisoned" => Ok(ConditionType::Poisoned), + "Prone" => Ok(ConditionType::Prone), + "Restrained" => Ok(ConditionType::Restrained), + "Stunned" => Ok(ConditionType::Stunned), + "Unconscious" => Ok(ConditionType::Unconscious), + _ => Err(()) + } + } +} diff --git a/src/db/schema.rs b/src/db/schema.rs index 016753d..a148271 100644 --- a/src/db/schema.rs +++ b/src/db/schema.rs @@ -17,6 +17,16 @@ diesel::table! { spells (id) { id -> Integer, name -> Text, + school -> Text, + level -> Integer, + ritual -> Bool, + concentration -> Bool, + classes -> Array, + damage_inflict -> Array, + damage_resist -> Array, + conditions -> Array, + saving_throw -> Array, + attack_type -> Nullable, data -> Jsonb } } \ No newline at end of file diff --git a/src/db/spells/model.rs b/src/db/spells/model.rs index 106ce8a..dc97cbb 100644 --- a/src/db/spells/model.rs +++ b/src/db/spells/model.rs @@ -3,29 +3,39 @@ use serde::{Deserialize, Serialize}; 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)] #[diesel(table_name = spells)] pub struct QuerySpell { pub id: i32, pub name: String, + pub school: String, + pub level: i32, + pub ritual: bool, + pub concentration: bool, + pub classes: Vec, + pub damage_inflict: Vec, + pub damage_resist: Vec, + pub conditions: Vec, + pub saving_throw: Vec, + pub attack_type: Option, pub data: serde_json::Value, } #[derive(Debug)] pub struct QueryFilters { pub by_name: Option, - pub by_schools: Option>, + pub by_schools: Option>, pub by_levels: Option>, pub by_ritual: Option, pub by_concentration: Option, pub by_classes: Option>, - pub by_damage_inflict: Option>, - pub by_damage_resist: Option>, - pub by_conditions: Option>, - pub by_saving_throw: Option>, - pub by_attack_type: Option, + pub by_damage_inflict: Option>, + pub by_damage_resist: Option>, + pub by_conditions: Option>, + pub by_saving_throw: Option>, + pub by_attack_type: Option, } impl Default for QueryFilters { @@ -53,15 +63,85 @@ impl QuerySpell { // Limit query to page and limit let offset = (page - 1) * limit; query = query.offset(offset as i64); - // Apply filters - if let Some(name) = filters.by_name.to_owned() { + 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::>())); + } + 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::>())); + } + 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::>())); + } + if let Some(conditions) = &filters.by_conditions { + query = query.filter(spells::conditions.overlaps_with(conditions.iter().map(|condition| condition.to_string()).collect::>())); + } + 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::>())); + } + if let Some(attack_type) = &filters.by_attack_type { + query = query.filter(spells::attack_type.eq(attack_type.to_string())); + } + let spells = query.load::(&mut conn)?; Ok(spells) } + pub fn get_count(filters: &QueryFilters) -> Result { + 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::>())); + } + 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::>())); + } + 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::>())); + } + if let Some(conditions) = &filters.by_conditions { + query = query.filter(spells::conditions.overlaps_with(conditions.iter().map(|condition| condition.to_string()).collect::>())); + } + 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::>())); + } + 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 { let mut conn = crate::db::connection()?; let spell = spells::table @@ -70,17 +150,6 @@ impl QuerySpell { Ok(spell) } - pub fn get_count(filters: &QueryFilters) -> Result { - 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 { let mut conn = crate::db::connection()?; 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)] pub struct InsertSpell { pub name: String, + pub school: String, + pub level: i32, + pub ritual: bool, + pub concentration: bool, + pub classes: Vec, + pub damage_inflict: Vec, + pub damage_resist: Vec, + pub conditions: Vec, + pub saving_throw: Vec, + pub attack_type: Option, pub data: serde_json::Value } @@ -174,13 +253,38 @@ impl Into for Spell { fn into(self) -> InsertSpell { return InsertSpell { 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::>(), + 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) { Ok(data) => data, Err(err) => { - log::error!("Failed to serialize spell description: {}", err); + log::error!("Failed to serialize spell: {}", err); serde_json::Value::Null } - }, + } } } } diff --git a/src/db/spells/routes.rs b/src/db/spells/routes.rs index 04cad71..303c229 100644 --- a/src/db/spells/routes.rs +++ b/src/db/spells/routes.rs @@ -1,4 +1,5 @@ use actix_web::{get, post, put, delete, web, HttpResponse, HttpRequest, ResponseError}; +use log::error; use serde::{Serialize, Deserialize}; use crate::{db::{spells::{QuerySpell, QueryFilters}, GetResponse, Metadata}, error_handler::ServiceError}; @@ -8,6 +9,16 @@ use super::{Spell, InsertSpell}; #[derive(Serialize, Deserialize)] struct GetAllParams { name: Option, + schools: Option, + levels: Option, + ritual: Option, + concentration: Option, + classes: Option, + damage_inflict: Option, + damage_resist: Option, + conditions: Option, + saving_throw: Option, + attack_type: Option, limit: Option, page: Option, } @@ -23,6 +34,43 @@ async fn get_all(req: HttpRequest) -> HttpResponse { }; let mut filters = QueryFilters::default(); filters.by_name = params.name.clone(); + filters.by_schools = match ¶ms.schools { + Some(schools) => Some(schools.split(",").map(|s| s.to_string()).collect()), + None => None + }; + filters.by_levels = match ¶ms.levels { + Some(levels) => Some(levels.split(",").map(|s| match s.to_string().parse::() { + Ok(level) => level, + Err(_) => 0 + }).collect()), + None => None + }; + filters.by_ritual = params.ritual; + filters.by_concentration = params.concentration; + filters.by_classes = match ¶ms.classes { + Some(classes) => Some(classes.split(",").map(|s| s.to_string()).collect()), + None => None + }; + filters.by_damage_inflict = match ¶ms.damage_inflict { + Some(damage_inflict) => Some(damage_inflict.split(",").map(|s| s.to_string()).collect()), + None => None + }; + filters.by_damage_resist = match ¶ms.damage_resist { + Some(damage_resist) => Some(damage_resist.split(",").map(|s| s.to_string()).collect()), + None => None + }; + filters.by_conditions = match ¶ms.conditions { + Some(conditions) => Some(conditions.split(",").map(|s| s.to_string()).collect()), + None => None + }; + filters.by_saving_throw = match ¶ms.saving_throw { + Some(saving_throw) => Some(saving_throw.split(",").map(|s| s.to_string()).collect()), + None => None + }; + filters.by_attack_type = match ¶ms.attack_type { + Some(attack_type) => Some(attack_type.split(",").map(|s| s.to_string()).collect()), + None => None + }; // Limit must be between 1 and 100 let limit = std::cmp::min(std::cmp::max(params.limit.unwrap_or(20), 1), 100); 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) -> HttpResponse { data: Spell::from(spell), 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) -> HttpResponse { async fn create(spell: web::Json) -> HttpResponse { match InsertSpell::insert(spell.into_inner().into()) { 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, spell: web::Json) -> HttpResponse }; match web::block(move || InsertSpell::update(id, spell.into_inner().into())).await.unwrap() { 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) -> HttpResponse { }; match web::block(move || QuerySpell::delete(id)).await.unwrap() { Ok(spell) => HttpResponse::Ok().json(Spell::from(spell)), - Err(err) => ResponseError::error_response(&err) + Err(err) => { + error!("{:?}", err.message); + ResponseError::error_response(&err) + } } } diff --git a/src/db/spells/types.rs b/src/db/spells/types.rs index bf1cde7..6e8f943 100644 --- a/src/db/spells/types.rs +++ b/src/db/spells/types.rs @@ -1,4 +1,4 @@ -// use std::str::FromStr; +use std::str::FromStr; use serde::{Deserialize, Serialize, ser::SerializeMap}; #[derive(Debug, Serialize, Deserialize)] @@ -21,43 +21,43 @@ pub enum SchoolType { Transmutation } -// impl SchoolType { -// pub fn to_string(&self) -> String { -// match self { -// SchoolType::Abjuration => "abjuration".to_string(), -// SchoolType::Conjuration => "conjuration".to_string(), -// SchoolType::Divination => "divination".to_string(), -// SchoolType::Enchantment => "enchantment".to_string(), -// SchoolType::Evocation => "evocation".to_string(), -// SchoolType::Illusion => "illusion".to_string(), -// SchoolType::Necromancy => "necromancy".to_string(), -// SchoolType::Transmutation => "transmutation".to_string() -// } -// } -// } +impl SchoolType { + pub fn to_string(&self) -> String { + match self { + SchoolType::Abjuration => "abjuration".to_string(), + SchoolType::Conjuration => "conjuration".to_string(), + SchoolType::Divination => "divination".to_string(), + SchoolType::Enchantment => "enchantment".to_string(), + SchoolType::Evocation => "evocation".to_string(), + SchoolType::Illusion => "illusion".to_string(), + SchoolType::Necromancy => "necromancy".to_string(), + SchoolType::Transmutation => "transmutation".to_string() + } + } +} -// impl FromStr for SchoolType { -// type Err = (); +impl FromStr for SchoolType { + type Err = (); -// fn from_str(s: &str) -> Result { -// match s { -// "abjuration" => Ok(SchoolType::Abjuration), -// "conjuration" => Ok(SchoolType::Conjuration), -// "divination" => Ok(SchoolType::Divination), -// "enchantment" => Ok(SchoolType::Enchantment), -// "evocation" => Ok(SchoolType::Evocation), -// "illusion" => Ok(SchoolType::Illusion), -// "necromancy" => Ok(SchoolType::Necromancy), -// "transmutation" => Ok(SchoolType::Transmutation), -// _ => Err(()) -// } -// } -// } + fn from_str(s: &str) -> Result { + match s { + "abjuration" => Ok(SchoolType::Abjuration), + "conjuration" => Ok(SchoolType::Conjuration), + "divination" => Ok(SchoolType::Divination), + "enchantment" => Ok(SchoolType::Enchantment), + "evocation" => Ok(SchoolType::Evocation), + "illusion" => Ok(SchoolType::Illusion), + "necromancy" => Ok(SchoolType::Necromancy), + "transmutation" => Ok(SchoolType::Transmutation), + _ => Err(()) + } + } +} #[derive(Debug, Serialize, Deserialize)] pub struct CastingTime { pub amount: i32, - #[serde(rename = "type")] + #[serde(rename = "unit")] pub casting_type: CastingType } @@ -110,26 +110,26 @@ pub enum SpellAttackType { Ranged, } -// impl SpellAttackType { -// pub fn to_string(&self) -> String { -// match self { -// SpellAttackType::Melee => "melee".to_string(), -// SpellAttackType::Ranged => "ranged".to_string() -// } -// } -// } +impl SpellAttackType { + pub fn to_string(&self) -> String { + match self { + SpellAttackType::Melee => "melee".to_string(), + SpellAttackType::Ranged => "ranged".to_string() + } + } +} -// impl FromStr for SpellAttackType { -// type Err = (); +impl FromStr for SpellAttackType { + type Err = (); -// fn from_str(s: &str) -> Result { -// match s { -// "melee" => Ok(SpellAttackType::Melee), -// "ranged" => Ok(SpellAttackType::Ranged), -// _ => Err(()) -// } -// } -// } + fn from_str(s: &str) -> Result { + match s { + "melee" => Ok(SpellAttackType::Melee), + "ranged" => Ok(SpellAttackType::Ranged), + _ => Err(()) + } + } +} #[derive(Debug, Serialize, Deserialize)] pub enum SpellDamageType { @@ -161,48 +161,48 @@ pub enum SpellDamageType { Thunder } -// impl SpellDamageType { -// pub fn to_string(&self) -> String { -// match self { -// SpellDamageType::Acid => "acid".to_string(), -// SpellDamageType::Bludgeoning => "bludgeoning".to_string(), -// SpellDamageType::Cold => "cold".to_string(), -// SpellDamageType::Fire => "fire".to_string(), -// SpellDamageType::Force => "force".to_string(), -// SpellDamageType::Lightning => "lightning".to_string(), -// SpellDamageType::Necrotic => "necrotic".to_string(), -// SpellDamageType::Piercing => "piercing".to_string(), -// SpellDamageType::Poison => "poison".to_string(), -// SpellDamageType::Psychic => "psychic".to_string(), -// SpellDamageType::Radiant => "radiant".to_string(), -// SpellDamageType::Slashing => "slashing".to_string(), -// SpellDamageType::Thunder => "thunder".to_string() -// } -// } -// } +impl SpellDamageType { + pub fn to_string(&self) -> String { + match self { + SpellDamageType::Acid => "acid".to_string(), + SpellDamageType::Bludgeoning => "bludgeoning".to_string(), + SpellDamageType::Cold => "cold".to_string(), + SpellDamageType::Fire => "fire".to_string(), + SpellDamageType::Force => "force".to_string(), + SpellDamageType::Lightning => "lightning".to_string(), + SpellDamageType::Necrotic => "necrotic".to_string(), + SpellDamageType::Piercing => "piercing".to_string(), + SpellDamageType::Poison => "poison".to_string(), + SpellDamageType::Psychic => "psychic".to_string(), + SpellDamageType::Radiant => "radiant".to_string(), + SpellDamageType::Slashing => "slashing".to_string(), + SpellDamageType::Thunder => "thunder".to_string() + } + } +} -// impl FromStr for SpellDamageType { -// type Err = (); +impl FromStr for SpellDamageType { + type Err = (); -// fn from_str(s: &str) -> Result { -// match s { -// "acid" => Ok(SpellDamageType::Acid), -// "bludgeoning" => Ok(SpellDamageType::Bludgeoning), -// "cold" => Ok(SpellDamageType::Cold), -// "fire" => Ok(SpellDamageType::Fire), -// "force" => Ok(SpellDamageType::Force), -// "lightning" => Ok(SpellDamageType::Lightning), -// "necrotic" => Ok(SpellDamageType::Necrotic), -// "piercing" => Ok(SpellDamageType::Piercing), -// "poison" => Ok(SpellDamageType::Poison), -// "psychic" => Ok(SpellDamageType::Psychic), -// "radiant" => Ok(SpellDamageType::Radiant), -// "slashing" => Ok(SpellDamageType::Slashing), -// "thunder" => Ok(SpellDamageType::Thunder), -// _ => Err(()) -// } -// } -// } + fn from_str(s: &str) -> Result { + match s { + "acid" => Ok(SpellDamageType::Acid), + "bludgeoning" => Ok(SpellDamageType::Bludgeoning), + "cold" => Ok(SpellDamageType::Cold), + "fire" => Ok(SpellDamageType::Fire), + "force" => Ok(SpellDamageType::Force), + "lightning" => Ok(SpellDamageType::Lightning), + "necrotic" => Ok(SpellDamageType::Necrotic), + "piercing" => Ok(SpellDamageType::Piercing), + "poison" => Ok(SpellDamageType::Poison), + "psychic" => Ok(SpellDamageType::Psychic), + "radiant" => Ok(SpellDamageType::Radiant), + "slashing" => Ok(SpellDamageType::Slashing), + "thunder" => Ok(SpellDamageType::Thunder), + _ => Err(()) + } + } +} #[derive(Debug, Serialize, Deserialize)] pub struct Range {