Skip to content

Commit

Permalink
refactor: increase linter rules (#84)
Browse files Browse the repository at this point in the history
* add pedantic rules
* add nursery rules
  • Loading branch information
RakuJa authored Dec 9, 2024
1 parent e674ecc commit 3f4daca
Show file tree
Hide file tree
Showing 40 changed files with 558 additions and 575 deletions.
19 changes: 17 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,21 @@ path = "src/main.rs"
unsafe_code = "forbid"
deprecated = "allow"

[lints.clippy]
struct_field_names = {level = "allow", priority = 2}
module_name_repetitions = {level = "allow", priority = 2}
# We are ok with losing some data without wrapping. We are not ok with wrapping
# Ex: 128.12 => 128 is ok, 128 => 0 is not.
cast_possible_truncation = {level = "allow", priority = 2}
cast_precision_loss = {level = "allow", priority = 2}

future_not_send = {level = "allow", priority = 2}

pedantic = {level = "warn", priority = 1}
nursery = {level= "warn", priority = 1}
# unwrap_used = {level = "warn", priority = 1}


[dependencies]
actix-web = "4.9.0"
actix-cors = "0.7.0"
Expand All @@ -40,8 +55,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.215", features = ["derive"] }
serde_json = "1.0.133"
serde = { version = "1.0.214", features = ["derive"] }
serde_json = "1.0.132"
strum = {version="0.26.3", features = ["derive"]}
fastrand = "2.2.0"
counter = "0.6.0"
Expand Down
2 changes: 1 addition & 1 deletion build/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ async fn main() {
.expect("Could not populate the db, something went wrong..");
creature_core_db_init::cleanup_db(&conn)
.await
.expect("Could not clean up the db. Dirty state detected, closing..")
.expect("Could not clean up the db. Dirty state detected, closing..");
}
20 changes: 10 additions & 10 deletions src/db/bestiary_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ pub async fn get_paginated_creatures(
let curr_slice: Vec<Creature> = filtered_list
.iter()
.skip(pagination.paginated_request.cursor as usize)
.take(pagination.paginated_request.page_size as usize)
.take(pagination.paginated_request.page_size.unsigned_abs() as usize)
.cloned()
.collect();

Expand All @@ -125,8 +125,7 @@ pub async fn get_creatures_passing_all_filters(
let mut creature_vec = Vec::new();
let level_vec = key_value_filters
.get(&CreatureFilter::Level)
.unwrap_or(&HashSet::new())
.clone();
.map_or_else(HashSet::new, std::clone::Clone::clone);
let modified_filters =
prepare_filters_for_db_communication(key_value_filters, fetch_weak, fetch_elite);
for core in
Expand Down Expand Up @@ -163,9 +162,9 @@ pub async fn get_all_possible_values_of_filter(
let mut x = match field {
CreatureFilter::Size => runtime_fields_values.list_of_sizes,
CreatureFilter::Rarity => runtime_fields_values.list_of_rarities,
CreatureFilter::Ranged => vec![true.to_string(), false.to_string()],
CreatureFilter::Melee => vec![true.to_string(), false.to_string()],
CreatureFilter::SpellCaster => vec![true.to_string(), false.to_string()],
CreatureFilter::Ranged | CreatureFilter::Melee | CreatureFilter::SpellCaster => {
vec![true.to_string(), false.to_string()]
}
CreatureFilter::Family => runtime_fields_values.list_of_families,
CreatureFilter::Traits => runtime_fields_values.list_of_traits,
CreatureFilter::Sources => runtime_fields_values.list_of_sources,
Expand Down Expand Up @@ -240,21 +239,22 @@ async fn get_list(app_state: &AppState, variant: CreatureVariant) -> Vec<Creatur
CreatureVariant::Base => creatures.into_iter().map(Creature::from_core).collect(),
_ => creatures
.into_iter()
.map(|cr| Creature::from_core_with_variant(cr, variant.clone()))
.map(|cr| Creature::from_core_with_variant(cr, variant))
.collect(),
};
}
vec![]
}

pub fn order_list_by_level(creature_list: Vec<Creature>) -> HashMap<i64, Vec<Creature>> {
pub fn order_list_by_level(creature_list: &[Creature]) -> HashMap<i64, Vec<Creature>> {
let mut ordered_by_level = HashMap::new();
creature_list.iter().for_each(|creature| {

for creature in creature_list {
ordered_by_level
.entry(creature.variant_data.level)
.or_insert_with(Vec::new)
.push(creature.clone());
});
}
ordered_by_level
}

Expand Down
2 changes: 1 addition & 1 deletion src/db/cr_core_initializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub async fn update_creature_core_table(conn: &Pool<Sqlite>) -> Result<()> {
hp: cr.hp,
base_level: cr.level,
size: cr.size,
family: cr.family.unwrap_or(String::from("-")),
family: cr.family.unwrap_or_else(|| String::from("-")),
rarity: cr.rarity,
license: cr.license,
remaster: cr.remaster,
Expand Down
40 changes: 14 additions & 26 deletions src/db/data_providers/creature_fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ async fn fetch_creature_weapons(conn: &Pool<Sqlite>, creature_id: i64) -> Result
el.weapon_data.damage_data = fetch_weapon_damage_data(conn, el.weapon_data.id)
.await
.unwrap_or(vec![]);
result_vec.push(el)
result_vec.push(el);
}
Ok(result_vec)
}
Expand Down Expand Up @@ -277,7 +277,7 @@ async fn fetch_creature_armors(conn: &Pool<Sqlite>, creature_id: i64) -> Result<
el.armor_data.property_runes = fetch_armor_runes(conn, el.armor_data.id)
.await
.unwrap_or(vec![]);
result_vec.push(el)
result_vec.push(el);
}
Ok(result_vec)
}
Expand All @@ -304,7 +304,7 @@ async fn fetch_creature_shields(conn: &Pool<Sqlite>, creature_id: i64) -> Result
.await
.unwrap_or(vec![]);
el.item_core.quantity = fetch_shield_quantity(conn, creature_id, el.shield_data.id).await;
result_vec.push(el)
result_vec.push(el);
}
Ok(result_vec)
}
Expand All @@ -326,80 +326,68 @@ async fn fetch_creature_items(conn: &Pool<Sqlite>, creature_id: i64) -> Result<V
for mut el in items {
el.traits = fetch_item_traits(conn, el.id).await.unwrap_or(vec![]);
el.quantity = fetch_item_quantity(conn, creature_id, el.id).await;
result_vec.push(el)
result_vec.push(el);
}
Ok(result_vec)
}
/// Quantities are present ONLY for creature's item.
/// It needs to be fetched from the association table.
/// It defaults to 1 if error are found
async fn fetch_item_quantity(conn: &Pool<Sqlite>, creature_id: i64, item_id: i64) -> i64 {
match sqlx::query!(
sqlx::query!(
"SELECT quantity FROM ITEM_CREATURE_ASSOCIATION_TABLE WHERE
creature_id == ($1) AND item_id == ($2)",
creature_id,
item_id
)
.fetch_one(conn)
.await
{
Ok(r) => r.quantity,
Err(_) => 1,
}
.map_or(1, |q| q.quantity)
}

/// Quantities are present ONLY for creature's weapons.
/// It needs to be fetched from the association table.
/// It defaults to 1 if error are found
async fn fetch_weapon_quantity(conn: &Pool<Sqlite>, creature_id: i64, weapon_id: i64) -> i64 {
match sqlx::query!(
sqlx::query!(
"SELECT quantity FROM WEAPON_CREATURE_ASSOCIATION_TABLE WHERE
creature_id == ($1) AND weapon_id == ($2)",
creature_id,
weapon_id
)
.fetch_one(conn)
.await
{
Ok(r) => r.quantity,
Err(_) => 1,
}
.map_or(1, |r| r.quantity)
}

/// Quantities are present ONLY for creature's shields.
/// It needs to be fetched from the association table.
/// It defaults to 1 if error are found
async fn fetch_shield_quantity(conn: &Pool<Sqlite>, creature_id: i64, shield_id: i64) -> i64 {
match sqlx::query!(
sqlx::query!(
"SELECT quantity FROM SHIELD_CREATURE_ASSOCIATION_TABLE WHERE
creature_id == ($1) AND shield_id == ($2)",
creature_id,
shield_id
)
.fetch_one(conn)
.await
{
Ok(r) => r.quantity,
Err(_) => 1,
}
.map_or(1, |r| r.quantity)
}

/// Quantities are present ONLY for creature's armors.
/// It needs to be fetched from the association table.
/// It defaults to 1 if error are found
async fn fetch_armor_quantity(conn: &Pool<Sqlite>, creature_id: i64, armor_id: i64) -> i64 {
match sqlx::query!(
sqlx::query!(
"SELECT quantity FROM ARMOR_CREATURE_ASSOCIATION_TABLE WHERE
creature_id == ($1) AND armor_id == ($2)",
creature_id,
armor_id
)
.fetch_one(conn)
.await
{
Ok(r) => r.quantity,
Err(_) => 1,
}
.map_or(1, |r| r.quantity)
}

async fn fetch_creature_actions(conn: &Pool<Sqlite>, creature_id: i64) -> Result<Vec<Action>> {
Expand Down Expand Up @@ -639,12 +627,12 @@ pub async fn fetch_creature_combat_data(
shields,
resistances: resistances
.iter()
.map(|x| (x.name.clone(), x.value as i16))
.map(|x| (x.name.clone(), i16::try_from(x.value).unwrap_or(0)))
.collect(),
immunities: immunities.iter().map(|x| x.name.clone()).collect(),
weaknesses: weaknesses
.iter()
.map(|x| (x.name.clone(), x.value as i16))
.map(|x| (x.name.clone(), i16::try_from(x.value).unwrap_or(0)))
.collect(),
saving_throws,
ac: creature_ac,
Expand Down
39 changes: 18 additions & 21 deletions src/db/data_providers/raw_query_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,45 +62,45 @@ pub fn prepare_filtered_get_creatures_core(
| CreatureFilter::Ranged
| CreatureFilter::SpellCaster => {
if !simple_core_query.is_empty() {
simple_core_query.push_str(" AND ")
simple_core_query.push_str(" AND ");
}
simple_core_query.push_str(
prepare_in_statement_for_generic_type(key.to_string().as_str(), value.iter())
.as_str(),
)
);
}
CreatureFilter::Family
| CreatureFilter::Alignment
| CreatureFilter::Size
| CreatureFilter::Rarity
| CreatureFilter::CreatureTypes => {
if !simple_core_query.is_empty() {
simple_core_query.push_str(" AND ")
simple_core_query.push_str(" AND ");
}
simple_core_query.push_str(
prepare_case_insensitive_in_statement(
key.to_string().as_str(),
value.iter().cloned(),
)
.as_str(),
)
);
}
CreatureFilter::Traits => {
trait_query.push_str(prepare_creature_trait_filter(value.iter().cloned()).as_str())
trait_query.push_str(prepare_creature_trait_filter(value.iter().cloned()).as_str());
}
CreatureFilter::CreatureRoles => {
if !simple_core_query.is_empty() {
simple_core_query.push_str(" AND ")
simple_core_query.push_str(" AND ");
}
simple_core_query
.push_str(prepare_bounded_or_check(value, ACCURACY_THRESHOLD, 100).as_str())
.push_str(prepare_bounded_or_check(value, ACCURACY_THRESHOLD, 100).as_str());
}
_ => (),
CreatureFilter::Sources => (), // Never given as value to filter
}
}
let mut where_query = simple_core_query.to_string();
if !trait_query.is_empty() {
where_query.push_str(format!(" AND id IN ({trait_query}) GROUP BY cc.id").as_str())
where_query.push_str(format!(" AND id IN ({trait_query}) GROUP BY cc.id").as_str());
}
if !where_query.is_empty() {
where_query = format!("WHERE {where_query}");
Expand Down Expand Up @@ -198,7 +198,7 @@ where
if result_string.ends_with(',') {
result_string.remove(result_string.len() - 1);
}
result_string.push(')')
result_string.push(')');
}
result_string
}
Expand All @@ -224,7 +224,7 @@ where
if result_string.ends_with(',') {
result_string.remove(result_string.len() - 1);
}
result_string.push(')')
result_string.push(')');
}
result_string
}
Expand Down Expand Up @@ -272,8 +272,8 @@ fn prepare_item_filter_statement(shop_filter_vectors: &ItemTableFieldsFilter) ->
prepare_case_insensitive_in_statement("source", shop_filter_vectors.source_filter.iter()),
prepare_bounded_check(
&String::from("level"),
shop_filter_vectors.min_level as i64,
shop_filter_vectors.max_level as i64,
i64::from(shop_filter_vectors.min_level),
i64::from(shop_filter_vectors.max_level),
),
]
.into_iter()
Expand All @@ -283,7 +283,7 @@ fn prepare_item_filter_statement(shop_filter_vectors: &ItemTableFieldsFilter) ->
if filters_query.is_empty() {
remaster_query
} else {
format!("{} AND {}", remaster_query, filters_query)
format!("{remaster_query} AND {filters_query}")
}
}

Expand All @@ -301,14 +301,11 @@ where
if whitelist_query.is_empty() && blacklist_query.is_empty() {
String::new()
} else if whitelist_query.is_empty() {
format!("id NOT IN ({})", blacklist_query)
format!("id NOT IN ({blacklist_query})")
} else if blacklist_query.is_empty() {
format!("id IN ({})", whitelist_query)
format!("id IN ({whitelist_query})")
} else {
format!(
"id IN ({}) AND id NOT IN ({})",
whitelist_query, blacklist_query
)
format!("id IN ({whitelist_query}) AND id NOT IN ({blacklist_query})")
}
}

Expand All @@ -320,7 +317,7 @@ fn prepare_get_id_matching_item_type_query(item_type: &ItemTypeEnum) -> String {
// There is no need for an and statement here, we already fetch from the "private" table.
// Item instead contains a lot of item_type (it's the base for weapon/shield/etc)
ItemTypeEnum::Weapon | ItemTypeEnum::Armor | ItemTypeEnum::Shield => {
("base_item_id", "".to_string())
("base_item_id", String::new())
}
};
let tass_item_id_field = match item_type {
Expand Down
Loading

0 comments on commit 3f4daca

Please sign in to comment.