From 70093bcf5cd04d57fe8ecf7e353d84c5f610d1dd Mon Sep 17 00:00:00 2001 From: RakuJa Date: Mon, 9 Dec 2024 15:37:30 +0000 Subject: [PATCH 1/3] chore: update libraries, bump MSRV, panic if update_cr_core is used more than once (#81) --- Cargo.toml | 7 ++++--- src/db/cr_core_initializer.rs | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a1b9091..d3bbd44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ authors = ["RakuJa"] # Compiler info edition = "2021" -rust-version = "1.75.0" +rust-version = "1.79.0" description = "Beyond Your Bestiary Explorer (BYBE) is a web service that provides tools to help Pathfinder 2e Game Masters." readme = "README.md" @@ -39,8 +39,8 @@ sqlx = { version = "0.8.2", features = ["runtime-async-std", "sqlite"] } cached = { version = "0.54.0", features = ["async"] } anyhow = "1.0.93" -serde = { version = "1.0.214", features = ["derive"] } -serde_json = "1.0.132" +serde = { version = "1.0.215", features = ["derive"] } +serde_json = "1.0.133" strum = {version="0.26.3", features = ["derive"]} fastrand = "2.2.0" counter = "0.6.0" @@ -56,6 +56,7 @@ dotenvy = "0.15.7" env_logger = "0.11.5" log = "0.4.22" once_cell = "1.20.2" +once = "0.3.4" [build-dependencies] tokio = { version = "1", features = ["macros", "rt-multi-thread", "rt"] } diff --git a/src/db/cr_core_initializer.rs b/src/db/cr_core_initializer.rs index 4076d8e..a4c5c60 100644 --- a/src/db/cr_core_initializer.rs +++ b/src/db/cr_core_initializer.rs @@ -9,12 +9,14 @@ use crate::models::creature::creature_metadata::type_enum::CreatureTypeEnum; use crate::models::shared::rarity_enum::RarityEnum; use crate::models::shared::size_enum::SizeEnum; use anyhow::{bail, Result}; +use once::assert_has_not_been_called; use serde::{Deserialize, Serialize}; use sqlx::{FromRow, Pool, Sqlite}; -/// Handler for startup, first creature_core initialization. Then it shouldn't be used - pub async fn update_creature_core_table(conn: &Pool) -> Result<()> { + assert_has_not_been_called!( + "Handler for startup, first creature_core initialization. Then it shouldn't be used" + ); let scales = fetch_creature_scales(conn).await?; for cr in get_creatures_raw_essential_data(conn, 0, -1).await? { let traits = fetch_creature_traits(conn, cr.id).await?; From 212a8b1278660db0ca78734f1c6ee331b106ce2e Mon Sep 17 00:00:00 2001 From: RakuJa Date: Mon, 9 Dec 2024 15:40:39 +0000 Subject: [PATCH 2/3] feat: add senses data (range, acuity, vision) (#82) * add senses data and vision field * update swagger * update DB version to download --- Makefile.toml | 2 +- setup.py | 6 +++--- src/db/data_providers/creature_fetcher.rs | 21 ++++++++++++++----- .../creature_component/creature_extra.rs | 4 +++- src/models/db/mod.rs | 2 +- src/models/db/raw_sense.rs | 7 ------- src/models/db/sense.rs | 11 ++++++++++ src/routes/bestiary.rs | 2 ++ 8 files changed, 37 insertions(+), 18 deletions(-) delete mode 100644 src/models/db/raw_sense.rs create mode 100644 src/models/db/sense.rs diff --git a/Makefile.toml b/Makefile.toml index 875268d..71c2a01 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -4,7 +4,7 @@ args = ["clean"] [tasks.prebuild] command = "python3" -args = ["setup.py", "--db_version", "2.3.0"] +args = ["setup.py", "--db_version", "2.4.0"] [tasks.format] install_crate = "rustfmt" diff --git a/setup.py b/setup.py index fc9d09e..ae863b6 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,7 @@ def handle_command_line_arguments() -> Optional[str]: if currentArgument in ("-h", "--help"): print("This script downloads or creates necessary file to build BYBE. \n" "Should be executed the first time the project is built in the machine or when resetting the database \n" - "Pass the --db_version or -v argument to input a specific BYBE-DB version to download (>= 2.3.0)") + "Pass the --db_version or -d argument to input a specific BYBE-DB version to download (>= 2.3.0)") elif currentArgument in ("-d", "--db_version"): return currentValue except getopt.error: @@ -33,8 +33,8 @@ def handle_command_line_arguments() -> Optional[str]: def main(): # Check if the file already exists or needs downloading - db_version: str = handle_command_line_arguments() or "2.3.0" - print(db_version) + db_version: str = handle_command_line_arguments() + print(f"Using DB version: {db_version}") or "2.3.0" # Oldest DB version publicly available remote_url: str = f"https://github.com/RakuJa/BYBE-DB/releases/download/v{db_version}/database.db" destination_file: str = "database.db" if not os.path.exists(destination_file): diff --git a/src/db/data_providers/creature_fetcher.rs b/src/db/data_providers/creature_fetcher.rs index 322777c..e866929 100644 --- a/src/db/data_providers/creature_fetcher.rs +++ b/src/db/data_providers/creature_fetcher.rs @@ -23,9 +23,9 @@ use crate::models::creature::items::spell_caster_entry::SpellCasterEntry; use crate::models::db::raw_immunity::RawImmunity; use crate::models::db::raw_language::RawLanguage; use crate::models::db::raw_resistance::RawResistance; -use crate::models::db::raw_sense::RawSense; use crate::models::db::raw_speed::RawSpeed; use crate::models::db::raw_weakness::RawWeakness; +use crate::models::db::sense::Sense; use crate::models::item::armor_struct::Armor; use crate::models::item::item_struct::Item; use crate::models::item::shield_struct::Shield; @@ -83,10 +83,10 @@ async fn fetch_creature_resistances( .await?) } -async fn fetch_creature_senses(conn: &Pool, creature_id: i64) -> Result> { +async fn fetch_creature_senses(conn: &Pool, creature_id: i64) -> Result> { Ok(sqlx::query_as!( - RawSense, - "SELECT * FROM SENSE_TABLE INTERSECT SELECT sense_id FROM SENSE_CREATURE_ASSOCIATION_TABLE WHERE creature_id == ($1)", + Sense, + "SELECT * FROM SENSE_TABLE WHERE id IN (SELECT sense_id FROM SENSE_CREATURE_ASSOCIATION_TABLE WHERE creature_id == ($1))", creature_id ).fetch_all(conn).await?) } @@ -188,6 +188,15 @@ async fn fetch_creature_perception(conn: &Pool, creature_id: i64) -> Res ) } +async fn fetch_creature_vision(conn: &Pool, creature_id: i64) -> Result { + Ok( + sqlx::query_scalar("SELECT vision FROM CREATURE_TABLE WHERE id = $1 LIMIT 1") + .bind(creature_id) + .fetch_one(conn) + .await?, + ) +} + async fn fetch_creature_perception_detail( conn: &Pool, creature_id: i64, @@ -577,6 +586,7 @@ pub async fn fetch_creature_extra_data( let ac_detail = fetch_creature_ac_detail(conn, creature_id).await?; let language_detail = fetch_creature_language_detail(conn, creature_id).await?; let perception = fetch_creature_perception(conn, creature_id).await?; + let has_vision = fetch_creature_vision(conn, creature_id).await?; let perception_detail = fetch_creature_perception_detail(conn, creature_id).await?; Ok(CreatureExtraData { @@ -584,7 +594,7 @@ pub async fn fetch_creature_extra_data( skills, items, languages: languages.iter().map(|x| x.name.clone()).collect(), - senses: senses.iter().map(|x| x.name.clone()).collect(), + senses, speeds: speeds .iter() .map(|x| (x.name.clone(), x.value as i16)) @@ -595,6 +605,7 @@ pub async fn fetch_creature_extra_data( language_detail, perception, perception_detail, + has_vision, }) } diff --git a/src/models/creature/creature_component/creature_extra.rs b/src/models/creature/creature_component/creature_extra.rs index 6d57bd4..85d0349 100644 --- a/src/models/creature/creature_component/creature_extra.rs +++ b/src/models/creature/creature_component/creature_extra.rs @@ -1,6 +1,7 @@ use crate::models::creature::creature_metadata::variant_enum::CreatureVariant; use crate::models::creature::items::action::Action; use crate::models::creature::items::skill::Skill; +use crate::models::db::sense::Sense; use crate::models::item::item_struct::Item; use serde::{Deserialize, Serialize}; #[allow(unused_imports)] // it's actually used in the example schema @@ -30,7 +31,7 @@ pub struct CreatureExtraData { pub skills: Vec, pub items: Vec, pub languages: Vec, - pub senses: Vec, + pub senses: Vec, #[schema(example = json!({"fly": 100, "swim": 50, "Base": 25}))] pub speeds: BTreeMap, pub ability_scores: AbilityScores, @@ -40,6 +41,7 @@ pub struct CreatureExtraData { #[schema(example = 0)] pub perception: i8, pub perception_detail: Option, + pub has_vision: bool, } impl CreatureExtraData { diff --git a/src/models/db/mod.rs b/src/models/db/mod.rs index 4891214..471eb1c 100644 --- a/src/models/db/mod.rs +++ b/src/models/db/mod.rs @@ -1,6 +1,6 @@ pub mod raw_immunity; pub mod raw_language; pub mod raw_resistance; -pub mod raw_sense; pub mod raw_speed; pub mod raw_weakness; +pub mod sense; diff --git a/src/models/db/raw_sense.rs b/src/models/db/raw_sense.rs deleted file mode 100644 index 0ed414b..0000000 --- a/src/models/db/raw_sense.rs +++ /dev/null @@ -1,7 +0,0 @@ -use serde::{Deserialize, Serialize}; -use sqlx::FromRow; - -#[derive(Serialize, Deserialize, FromRow)] -pub struct RawSense { - pub name: String, -} diff --git a/src/models/db/sense.rs b/src/models/db/sense.rs new file mode 100644 index 0000000..8a24e74 --- /dev/null +++ b/src/models/db/sense.rs @@ -0,0 +1,11 @@ +use serde::{Deserialize, Serialize}; +use sqlx::FromRow; +use utoipa::ToSchema; + +#[derive(Serialize, Deserialize, FromRow, ToSchema, Clone, Eq, Hash, PartialEq)] +pub struct Sense { + pub id: i64, + pub name: String, + pub range: Option, + pub acuity: Option, +} diff --git a/src/routes/bestiary.rs b/src/routes/bestiary.rs index 9aa98a6..a341f01 100644 --- a/src/routes/bestiary.rs +++ b/src/routes/bestiary.rs @@ -29,6 +29,7 @@ use crate::models::item::weapon_struct::Weapon; use crate::models::bestiary_structs::CreatureSortEnum; use crate::models::bestiary_structs::{BestiaryPaginatedRequest, BestiarySortData}; +use crate::models::db::sense::Sense; use crate::models::routers_validator_structs::{CreatureFieldFilters, PaginatedRequest}; use crate::services::bestiary_service; use crate::services::bestiary_service::BestiaryResponse; @@ -87,6 +88,7 @@ pub fn init_docs(doc: &mut utoipa::openapi::OpenApi) { CreatureExtraData, CreatureCombatData, CreatureSpellCasterData, + Sense, Spell, Shield, Weapon, From e674eccdaa1b3afe9b8c8d039997b3cb981b8dbf Mon Sep 17 00:00:00 2001 From: RakuJa Date: Mon, 9 Dec 2024 15:45:11 +0000 Subject: [PATCH 3/3] feat: align bestiary list api with shop (#83) * align bestiary listing API with shop, moving to POST and allowing array for filters (multiple filters values for one filter) * keep old bestiary listing GET but marking as deprecated (will be removed in a few months) --- Cargo.toml | 1 + src/models/creature/creature_struct.rs | 51 ++++++++-------- src/models/item/item_struct.rs | 11 ++-- src/models/routers_validator_structs.rs | 26 ++++----- src/routes/bestiary.rs | 77 ++++++++++++++++++------- src/routes/shop.rs | 11 +--- src/services/bestiary_service.rs | 2 +- src/services/mod.rs | 1 + src/services/sanitizer.rs | 9 +++ src/services/url_calculator.rs | 24 -------- 10 files changed, 115 insertions(+), 98 deletions(-) create mode 100644 src/services/sanitizer.rs diff --git a/Cargo.toml b/Cargo.toml index d3bbd44..f9b523f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ path = "src/main.rs" [lints.rust] unsafe_code = "forbid" +deprecated = "allow" [dependencies] actix-web = "4.9.0" diff --git a/src/models/creature/creature_struct.rs b/src/models/creature/creature_struct.rs index 71b6c2a..6b66fd7 100644 --- a/src/models/creature/creature_struct.rs +++ b/src/models/creature/creature_struct.rs @@ -120,20 +120,17 @@ impl Creature { } fn check_creature_pass_equality_filters(&self, filters: &CreatureFieldFilters) -> bool { - filters - .rarity_filter - .as_ref() - .map_or(true, |rarity| self.core_data.essential.rarity == *rarity) - && filters - .size_filter - .as_ref() - .map_or(true, |size| self.core_data.essential.size == *size) - && filters.alignment_filter.as_ref().map_or(true, |alignment| { - self.core_data.essential.alignment == *alignment - }) - && filters - .is_melee_filter - .map_or(true, |is_melee| self.core_data.derived.is_melee == is_melee) + filters.rarity_filter.as_ref().map_or(true, |x| { + x.iter() + .any(|rarity| self.core_data.essential.rarity == *rarity) + }) && filters.size_filter.as_ref().map_or(true, |x| { + x.iter().any(|size| self.core_data.essential.size == *size) + }) && filters.alignment_filter.as_ref().map_or(true, |x| { + x.iter() + .any(|align| self.core_data.essential.alignment == *align) + }) && filters + .is_melee_filter + .map_or(true, |is_melee| self.core_data.derived.is_melee == is_melee) && filters.is_ranged_filter.map_or(true, |is_ranged| { self.core_data.derived.is_ranged == is_ranged }) @@ -142,14 +139,14 @@ impl Creature { .map_or(true, |is_spell_caster| { self.core_data.derived.is_spell_caster == is_spell_caster }) - && filters - .type_filter - .as_ref() - .map_or(true, |cr_type| self.core_data.essential.cr_type == *cr_type) + && filters.type_filter.as_ref().map_or(true, |x| { + x.iter() + .any(|cr_type| self.core_data.essential.cr_type == *cr_type) + }) && (filters.role_threshold.is_none() || filters.role_filter.as_ref().map_or(true, |cr_role| { let t = filters.role_threshold.unwrap_or(0); - match cr_role { + cr_role.iter().any(|role| match role { CreatureRoleEnum::Brute => self.core_data.derived.brute_percentage >= t, CreatureRoleEnum::MagicalStriker => { self.core_data.derived.magical_striker_percentage >= t @@ -165,7 +162,7 @@ impl Creature { CreatureRoleEnum::SpellCaster => { self.core_data.derived.spell_caster_percentage >= t } - } + }) })) && match filters.pathfinder_version.clone().unwrap_or_default() { PathfinderVersionEnum::Legacy => !self.core_data.essential.remaster, @@ -176,13 +173,19 @@ impl Creature { fn check_creature_pass_string_filters(&self, filters: &CreatureFieldFilters) -> bool { filters.name_filter.as_ref().map_or(true, |name| { - self.core_data.essential.name.to_lowercase().contains(name) - }) && filters.family_filter.as_ref().map_or(true, |name| { self.core_data .essential - .family + .name .to_lowercase() - .contains(name) + .contains(name.to_lowercase().as_str()) + }) && filters.family_filter.as_ref().map_or(true, |x| { + x.iter().any(|fam| { + self.core_data + .essential + .family + .to_lowercase() + .contains(fam.to_lowercase().as_str()) + }) }) } } diff --git a/src/models/item/item_struct.rs b/src/models/item/item_struct.rs index 40ae12e..a35559b 100644 --- a/src/models/item/item_struct.rs +++ b/src/models/item/item_struct.rs @@ -156,6 +156,11 @@ impl Item { .type_filter .as_ref() .map_or(true, |x| x.iter().any(|t_filt| self.item_type == *t_filt)) + && match filters.pathfinder_version.clone().unwrap_or_default() { + PathfinderVersionEnum::Legacy => !self.remaster, + PathfinderVersionEnum::Remaster => self.remaster, + PathfinderVersionEnum::Any => true, + } } fn check_item_pass_string_filters(&self, filters: &ItemFieldFilters) -> bool { @@ -171,11 +176,7 @@ impl Item { .to_lowercase() .contains(cat.to_lowercase().as_str()) }) - }) && match filters.pathfinder_version.clone().unwrap_or_default() { - PathfinderVersionEnum::Legacy => !self.remaster, - PathfinderVersionEnum::Remaster => self.remaster, - PathfinderVersionEnum::Any => true, - } && filters.source_filter.as_ref().map_or(true, |x| { + }) && filters.source_filter.as_ref().map_or(true, |x| { x.iter().any(|source| { self.source .to_lowercase() diff --git a/src/models/routers_validator_structs.rs b/src/models/routers_validator_structs.rs index fa0f5b1..37ade05 100644 --- a/src/models/routers_validator_structs.rs +++ b/src/models/routers_validator_structs.rs @@ -8,25 +8,25 @@ use crate::models::shared::size_enum::SizeEnum; use serde::{Deserialize, Serialize}; use strum::Display; use utoipa::{IntoParams, ToSchema}; -#[derive(Serialize, Deserialize, IntoParams)] +#[derive(Serialize, Deserialize, IntoParams, ToSchema)] pub struct CreatureFieldFilters { pub name_filter: Option, - pub source_filter: Option, - pub family_filter: Option, - pub rarity_filter: Option, - pub size_filter: Option, - pub alignment_filter: Option, - pub role_filter: Option, - pub type_filter: Option, - #[param(minimum = 0, maximum = 100, example = 50)] + pub source_filter: Option>, + pub family_filter: Option>, + pub rarity_filter: Option>, + pub size_filter: Option>, + pub alignment_filter: Option>, + pub role_filter: Option>, + pub type_filter: Option>, + #[schema(minimum = 0, maximum = 100, example = 50)] pub role_threshold: Option, - #[param(minimum = 0, example = 0)] + #[schema(minimum = 0, example = 0)] pub min_hp_filter: Option, - #[param(minimum = 0, example = 100)] + #[schema(minimum = 0, example = 100)] pub max_hp_filter: Option, - #[param(minimum = -1, example = -1)] + #[schema(minimum = -1, example = -1)] pub min_level_filter: Option, - #[param(minimum = -1, example = 5)] + #[schema(minimum = -1, example = 5)] pub max_level_filter: Option, pub is_melee_filter: Option, pub is_ranged_filter: Option, diff --git a/src/routes/bestiary.rs b/src/routes/bestiary.rs index a341f01..8a0ff22 100644 --- a/src/routes/bestiary.rs +++ b/src/routes/bestiary.rs @@ -33,9 +33,10 @@ use crate::models::db::sense::Sense; use crate::models::routers_validator_structs::{CreatureFieldFilters, PaginatedRequest}; use crate::services::bestiary_service; use crate::services::bestiary_service::BestiaryResponse; +use crate::services::sanitizer::sanitize_id; use crate::AppState; use actix_web::web::Query; -use actix_web::{error, get, web, Responder, Result}; +use actix_web::{get, post, web, Responder}; use utoipa::OpenApi; pub fn init_endpoints(cfg: &mut web::ServiceConfig) { @@ -61,6 +62,7 @@ pub fn init_docs(doc: &mut utoipa::openapi::OpenApi) { #[openapi( paths( get_bestiary, + get_bestiary_listing, get_families_list, get_traits_list, get_sources_list, @@ -122,14 +124,15 @@ pub fn init_docs(doc: &mut utoipa::openapi::OpenApi) { ), )] #[get("/list")] +#[deprecated(since = "2.4.0", note = "please use `get_bestiary_listing` instead")] pub async fn get_bestiary( data: web::Data, filters: Query, pagination: Query, sort_data: Query, -) -> Result { +) -> actix_web::Result { Ok(web::Json( - bestiary_service::get_bestiary( + bestiary_service::get_bestiary_listing( &data, &filters.0, &BestiaryPaginatedRequest { @@ -141,6 +144,42 @@ pub async fn get_bestiary( )) } +#[utoipa::path( + post, + path = "/bestiary/list", + tag = "bestiary", + request_body( + content = CreatureFieldFilters, + content_type = "application/json" + ), + params( + PaginatedRequest, BestiarySortData + ), + responses( + (status=200, description = "Successful Response", body = BestiaryResponse), + (status=400, description = "Bad request.") + ), +)] +#[post("/list")] +pub async fn get_bestiary_listing( + data: web::Data, + web::Json(body): web::Json, + pagination: Query, + sort_data: Query, +) -> actix_web::Result { + Ok(web::Json( + bestiary_service::get_bestiary_listing( + &data, + &body, + &BestiaryPaginatedRequest { + paginated_request: pagination.0, + bestiary_sort_data: sort_data.0, + }, + ) + .await, + )) +} + #[utoipa::path( get, path = "/bestiary/families", @@ -154,7 +193,7 @@ pub async fn get_bestiary( ), )] #[get("/families")] -pub async fn get_families_list(data: web::Data) -> Result { +pub async fn get_families_list(data: web::Data) -> actix_web::Result { Ok(web::Json(bestiary_service::get_families_list(&data).await)) } @@ -171,7 +210,7 @@ pub async fn get_families_list(data: web::Data) -> Result) -> Result { +pub async fn get_traits_list(data: web::Data) -> actix_web::Result { Ok(web::Json(bestiary_service::get_traits_list(&data).await)) } @@ -188,7 +227,7 @@ pub async fn get_traits_list(data: web::Data) -> Result) -> Result { +pub async fn get_sources_list(data: web::Data) -> actix_web::Result { Ok(web::Json(bestiary_service::get_sources_list(&data).await)) } @@ -205,7 +244,7 @@ pub async fn get_sources_list(data: web::Data) -> Result) -> Result { +pub async fn get_rarities_list(data: web::Data) -> actix_web::Result { Ok(web::Json(bestiary_service::get_rarities_list(&data).await)) } @@ -222,7 +261,7 @@ pub async fn get_rarities_list(data: web::Data) -> Result) -> Result { +pub async fn get_sizes_list(data: web::Data) -> actix_web::Result { Ok(web::Json(bestiary_service::get_sizes_list(&data).await)) } @@ -239,7 +278,7 @@ pub async fn get_sizes_list(data: web::Data) -> Result ), )] #[get("/alignments")] -pub async fn get_alignments_list(data: web::Data) -> Result { +pub async fn get_alignments_list(data: web::Data) -> actix_web::Result { Ok(web::Json( bestiary_service::get_alignments_list(&data).await, )) @@ -258,7 +297,9 @@ pub async fn get_alignments_list(data: web::Data) -> Result) -> Result { +pub async fn get_creature_types_list( + data: web::Data, +) -> actix_web::Result { Ok(web::Json( bestiary_service::get_creature_types_list(&data).await, )) @@ -277,7 +318,7 @@ pub async fn get_creature_types_list(data: web::Data) -> Result Result { +pub async fn get_creature_roles_list() -> actix_web::Result { Ok(web::Json(bestiary_service::get_creature_roles_list().await)) } @@ -299,7 +340,7 @@ pub async fn get_creature( data: web::Data, creature_id: web::Path, response_data_mods: Query, -) -> Result { +) -> actix_web::Result { Ok(web::Json( bestiary_service::get_creature(&data, sanitize_id(&creature_id)?, &response_data_mods.0) .await, @@ -324,7 +365,7 @@ pub async fn get_elite_creature( data: web::Data, creature_id: web::Path, response_data_mods: Query, -) -> Result { +) -> actix_web::Result { Ok(web::Json( bestiary_service::get_elite_creature( &data, @@ -353,7 +394,7 @@ pub async fn get_weak_creature( data: web::Data, creature_id: web::Path, response_data_mods: Query, -) -> Result { +) -> actix_web::Result { Ok(web::Json( bestiary_service::get_weak_creature( &data, @@ -363,11 +404,3 @@ pub async fn get_weak_creature( .await, )) } - -fn sanitize_id(creature_id: &str) -> Result { - let id = creature_id.parse::(); - match id { - Ok(s) => Ok(s), - Err(e) => Err(error::ErrorNotFound(e)), - } -} diff --git a/src/routes/shop.rs b/src/routes/shop.rs index d4689d8..da830e7 100644 --- a/src/routes/shop.rs +++ b/src/routes/shop.rs @@ -12,11 +12,12 @@ use crate::models::shop_structs::ShopTemplateData; use crate::models::shop_structs::ShopTemplateEnum; use crate::models::shop_structs::{ItemSortEnum, ShopPaginatedRequest}; use crate::models::shop_structs::{RandomShopData, ShopSortData}; +use crate::services::sanitizer::sanitize_id; use crate::services::shop_service; use crate::services::shop_service::ShopListingResponse; use crate::AppState; use actix_web::web::Query; -use actix_web::{error, get, post, web, Responder}; +use actix_web::{get, post, web, Responder}; use utoipa::OpenApi; pub fn init_endpoints(cfg: &mut web::ServiceConfig) { @@ -201,11 +202,3 @@ pub async fn get_items_traits_list(data: web::Data) -> actix_web::Resu pub async fn get_templates_data() -> actix_web::Result { Ok(web::Json(shop_service::get_shop_templates_data().await)) } - -fn sanitize_id(creature_id: &str) -> actix_web::Result { - let id = creature_id.parse::(); - match id { - Ok(s) => Ok(s), - Err(e) => Err(error::ErrorNotFound(e)), - } -} diff --git a/src/services/bestiary_service.rs b/src/services/bestiary_service.rs index 1eabff1..566fffd 100644 --- a/src/services/bestiary_service.rs +++ b/src/services/bestiary_service.rs @@ -54,7 +54,7 @@ pub async fn get_weak_creature( } } -pub async fn get_bestiary( +pub async fn get_bestiary_listing( app_state: &AppState, field_filter: &CreatureFieldFilters, pagination: &BestiaryPaginatedRequest, diff --git a/src/services/mod.rs b/src/services/mod.rs index 8eb26ed..3b56e67 100644 --- a/src/services/mod.rs +++ b/src/services/mod.rs @@ -1,5 +1,6 @@ pub mod bestiary_service; pub mod encounter_handler; pub mod encounter_service; +pub mod sanitizer; pub mod shop_service; pub mod url_calculator; diff --git a/src/services/sanitizer.rs b/src/services/sanitizer.rs new file mode 100644 index 0000000..6d0dea4 --- /dev/null +++ b/src/services/sanitizer.rs @@ -0,0 +1,9 @@ +use actix_web::error; + +pub fn sanitize_id(creature_id: &str) -> actix_web::Result { + let id = creature_id.parse::(); + match id { + Ok(s) => Ok(s), + Err(e) => Err(error::ErrorNotFound(e)), + } +} diff --git a/src/services/url_calculator.rs b/src/services/url_calculator.rs index 5ae554e..20af47b 100644 --- a/src/services/url_calculator.rs +++ b/src/services/url_calculator.rs @@ -65,30 +65,6 @@ fn creature_filter_query_calculator(field_filters: &CreatureFieldFilters) -> Str .name_filter .clone() .map(|name| format!("name_filter={}", name)), - field_filters - .family_filter - .clone() - .map(|fam| format!("family_filter={}", fam)), - field_filters - .rarity_filter - .clone() - .map(|rar| format!("rarity_filter={}", rar)), - field_filters - .size_filter - .clone() - .map(|size| format!("size_filter={}", size)), - field_filters - .alignment_filter - .clone() - .map(|align| format!("alignment_filter={}", align)), - field_filters - .role_filter - .clone() - .map(|role| format!("role_filter={}", role)), - field_filters - .type_filter - .clone() - .map(|cr_type| format!("type_filter={}", cr_type)), field_filters .role_threshold .map(|threshold| format!("role_threshold={}", threshold)),