diff --git a/common/assets/src/lib.rs b/common/assets/src/lib.rs index d9dd19c3e3..43bca38377 100644 --- a/common/assets/src/lib.rs +++ b/common/assets/src/lib.rs @@ -1,3 +1,4 @@ +//#![warn(clippy::pedantic)] //! Load assets (images or voxel data) from files use dot_vox::DotVoxData; @@ -86,6 +87,18 @@ pub trait AssetExt: Sized + Send + Sync + 'static { fn get_or_insert(specifier: &str, default: Self) -> AssetHandle; } +/// Loads directory and all files in it +/// +/// NOTE: If you call `.iter()` on it, all failed files will be ignored +/// If you want to handle errors, call `.ids()` which will return +/// iterator over assets specifiers +/// +/// # Errors +/// An error is returned if the given id does not match a valid readable +/// directory. +/// +/// When loading a directory recursively, directories that can't be read are +/// ignored. pub fn load_dir( specifier: &str, recursive: bool, @@ -94,10 +107,20 @@ pub fn load_dir( ASSETS.load_dir(specifier, recursive) } +/// Loads directory and all files in it +/// +/// # Panics +/// 1) If can't load directory (filesystem errors) +/// 2) If file can't be loaded (parsing problem) #[track_caller] -pub fn load_expect_dir(specifier: &str, recursive: bool) -> AssetDirHandle { - load_dir(specifier, recursive) - .unwrap_or_else(|e| panic!("Failed loading directory. error={:?}", e)) +pub fn read_expect_dir( + specifier: &str, + recursive: bool, +) -> impl Iterator> { + load_dir::(specifier, recursive) + .unwrap_or_else(|e| panic!("Failed loading directory {}. error={:?}", e, specifier)) + .ids() + .map(|entry| T::load_expect(entry).read()) } impl AssetExt for T { @@ -266,8 +289,7 @@ mod tests { .filter(|path| path.is_file()) .filter(|path| { path.extension() - .map(|e| ext == e.to_ascii_lowercase()) - .unwrap_or(false) + .map_or(false, |e| ext == e.to_ascii_lowercase()) }) .for_each(|path| { let file = File::open(&path).expect("Failed to open the file"); @@ -280,7 +302,6 @@ mod tests { } } -#[warn(clippy::pedantic)] #[cfg(feature = "asset_tweak")] pub mod asset_tweak { use super::{find_root, Asset, AssetExt, RonLoader}; @@ -300,7 +321,6 @@ pub mod asset_tweak { const EXTENSION: &'static str = "ron"; } - #[must_use] /// # Usage /// Create file with content which represent tweaked value /// @@ -329,7 +349,6 @@ pub mod asset_tweak { value } - #[must_use] /// # Usage /// Will create file "assets/tweak/{specifier}.ron" if not exists /// and return passed `value`. diff --git a/common/src/comp/inventory/item/mod.rs b/common/src/comp/inventory/item/mod.rs index 7861660d60..171c63d89b 100644 --- a/common/src/comp/inventory/item/mod.rs +++ b/common/src/comp/inventory/item/mod.rs @@ -625,6 +625,7 @@ impl Item { pub fn new_from_asset_glob(asset_glob: &str) -> Result, Error> { let specifier = asset_glob.strip_suffix(".*").unwrap_or(asset_glob); let defs = assets::load_dir::(specifier, true)?; + // use ids() instead of iter() because we don't want to ignore errors defs.ids().map(Item::new_from_asset).collect() } @@ -893,7 +894,8 @@ mod tests { #[test] fn test_assets_items() { - let defs = assets::load_expect_dir::("common.items", true); + let defs = assets::load_dir::("common.items", true) + .expect("Failed to access items directory"); for item in defs.ids().map(Item::new_from_asset_expect) { std::mem::drop(item) } diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs index 4c500dff97..61b2da5dd8 100644 --- a/common/src/comp/inventory/loadout_builder.rs +++ b/common/src/comp/inventory/loadout_builder.rs @@ -736,10 +736,9 @@ mod tests { // It just load everything that could // TODO: add some checks, e.g. that Armor(Head) key correspond // to Item with ItemKind Head(_) - let loadouts = assets::load_expect_dir::("common.loadout", true); - for loadout in loadouts.iter() { - let spec = loadout.read(); - for (&key, entry) in &spec.0 { + let loadouts = assets::read_expect_dir::("common.loadout", true); + for loadout in loadouts { + for (&key, entry) in &loadout.0 { entry.validate(key); } } diff --git a/common/src/generation.rs b/common/src/generation.rs index 37cc56c2f8..e5a46562c0 100644 --- a/common/src/generation.rs +++ b/common/src/generation.rs @@ -312,8 +312,8 @@ mod tests { #[test] fn test_all_entity_assets() { // It just load everything that could - let entity_configs = assets::load_expect_dir::("common.entity", true); - for config in entity_configs.iter() { + let entity_configs = assets::read_expect_dir::("common.entity", true); + for config in entity_configs { let EntityConfig { main_tool, second_tool, @@ -322,7 +322,7 @@ mod tests { name: _name, body, loot, - } = config.cloned(); + } = config.clone(); if let Some(main_tool) = main_tool { main_tool.validate(EquipSlot::ActiveMainhand); diff --git a/common/src/lottery.rs b/common/src/lottery.rs index 368ccb1096..3dbb80aca9 100644 --- a/common/src/lottery.rs +++ b/common/src/lottery.rs @@ -146,9 +146,9 @@ mod tests { } let loot_tables = - assets::load_expect_dir::>>("common.loot_tables", true); - for loot_table in loot_tables.iter() { - validate_table_contents(loot_table.cloned()); + assets::read_expect_dir::>>("common.loot_tables", true); + for loot_table in loot_tables { + validate_table_contents(loot_table.clone()); } } } diff --git a/common/src/skillset_builder.rs b/common/src/skillset_builder.rs index 5cdab8377c..d0e7b2ecc0 100644 --- a/common/src/skillset_builder.rs +++ b/common/src/skillset_builder.rs @@ -40,7 +40,7 @@ fn skills_from_nodes(nodes: &[SkillNode]) -> Vec<(Skill, Option)> { for node in nodes { match node { SkillNode::Tree(asset) => { - skills.append(&mut skills_from_asset_expect(&asset)); + skills.append(&mut skills_from_asset_expect(asset)); }, SkillNode::Skill(req) => { skills.push(*req); @@ -151,11 +151,11 @@ mod tests { #[test] fn test_all_skillset_assets() { - let skillsets = assets::load_expect_dir::("common.skillset", true); - for skillset in skillsets.iter() { + let skillsets = assets::read_expect_dir::("common.skillset", true); + for skillset in skillsets { std::mem::drop({ let mut skillset_builder = SkillSetBuilder::default(); - let nodes = &*skillset.read().0; + let nodes = &*skillset.0; let tree = skills_from_nodes(nodes); for (skill, level) in tree { skillset_builder = skillset_builder.with_skill(skill, level); diff --git a/voxygen/i18n/src/data.rs b/voxygen/i18n/src/data.rs index 7e5e3b090c..94fbb25d98 100644 --- a/voxygen/i18n/src/data.rs +++ b/voxygen/i18n/src/data.rs @@ -372,7 +372,8 @@ impl assets::Compound for LocalizationList { specifier: &str, ) -> Result { // List language directories - let languages = assets::load_expect_dir::(specifier, false) + let languages = assets::load_dir::(specifier, false) + .unwrap_or_else(|e| panic!("Failed to get manifests from {}: {:?}", specifier, e)) .ids() .filter_map(|spec| cache.load::(spec).ok()) .map(|localization| localization.read().metadata.clone()) diff --git a/world/src/site/settlement/mod.rs b/world/src/site/settlement/mod.rs index 49df5bd78d..8fce212e14 100644 --- a/world/src/site/settlement/mod.rs +++ b/world/src/site/settlement/mod.rs @@ -1038,7 +1038,7 @@ fn merchant_loadout( let rng = &mut rand::thread_rng(); // Fill backpack with ingredients and coins - let backpack = ingredient_bag(economy, rng); + let backpack = ingredient_backpack(economy, rng); // Fill bags with stuff let (food_bag, potion_bag) = consumable_bags(economy, rng); @@ -1066,7 +1066,7 @@ fn sort_bag(bag: &mut Item) { fn armor_bag(economy: Option<&trade::SiteInformation>) -> Item { #![warn(clippy::pedantic)] - let mut bag = Item::new_from_asset_expect("common.items.armor.misc.back.backpack"); + let mut bag = Item::new_from_asset_expect("common.items.armor.misc.bag.sturdy_red_backpack"); let armor_items = economy .and_then(|e| e.unconsumed_stock.get(&Good::Armor)) @@ -1115,10 +1115,10 @@ fn weapon_bag(economy: Option<&trade::SiteInformation>) -> Item { bag } -fn ingredient_bag(economy: Option<&trade::SiteInformation>, rng: &mut impl Rng) -> Item { +fn ingredient_backpack(economy: Option<&trade::SiteInformation>, rng: &mut impl Rng) -> Item { #![warn(clippy::pedantic)] - let mut bag = Item::new_from_asset_expect("common.items.armor.misc.bag.sturdy_red_backpack"); + let mut bag = Item::new_from_asset_expect("common.items.armor.misc.back.backpack"); let slots = bag.slots_mut(); // It's safe to truncate here, because coins clamped to 3000 max diff --git a/world/src/site2/plot/dungeon.rs b/world/src/site2/plot/dungeon.rs index 5f4cf61a1a..2b6a0126fe 100644 --- a/world/src/site2/plot/dungeon.rs +++ b/world/src/site2/plot/dungeon.rs @@ -264,7 +264,7 @@ impl Room { match self.difficulty { 3 => { let turret = turret - .with_body(comp::Body::Object(comp::object::Body::Crossbow)) + .with_body(comp::Body::Object(comp::object::Body::HaniwaSentry)) .with_asset_expect("common.entity.dungeon.tier-3.sentry"); supplement.add_entity(turret); },