fix(simulation): replace HashMap/HashSet with BTreeMap/BTreeSet in generate_corporations

Project Clippy config disallows std::collections::HashMap and HashSet.
Replaced all usages with BTreeMap/BTreeSet. Also fixed:
- Unnecessary if-let on iterator rows (use flatten() instead)
- contains_key + insert on BTreeMap (use entry().or_insert_with())

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-07 22:44:23 +02:00
co-authored by Claude Sonnet 4.6
parent b19bfb3239
commit 822fe488d6
+48 -74
View File
@@ -17,7 +17,7 @@
//! cargo run --bin generate_corporations -- --seed 42 --min-corps 5000
//! ```
use std::collections::{BTreeMap, HashMap, HashSet};
use std::collections::{BTreeMap, BTreeSet};
use std::path::PathBuf;
use std::process;
@@ -246,11 +246,7 @@ fn load_locations(conn: &Connection) -> Vec<Location> {
})
})
.unwrap();
for row in body_rows {
if let Ok(loc) = row {
locations.push(loc);
}
}
locations.extend(body_rows.flatten());
// Stations with population
let mut stmt = conn
@@ -275,11 +271,7 @@ fn load_locations(conn: &Connection) -> Vec<Location> {
})
})
.unwrap();
for row in station_rows {
if let Ok(loc) = row {
locations.push(loc);
}
}
locations.extend(station_rows.flatten());
locations
}
@@ -305,7 +297,7 @@ fn load_existing_corps(conn: &Connection) -> Vec<ExistingCorp> {
.collect()
}
fn load_commodity_ids(conn: &Connection) -> HashSet<String> {
fn load_commodity_ids(conn: &Connection) -> BTreeSet<String> {
let mut stmt = conn
.prepare("SELECT commodity_id FROM commodities")
.unwrap();
@@ -469,7 +461,7 @@ fn assign_brands(
}
// Pick 1-4 brands weighted by relevance to the lore archetype's commodities
let all_commodities: HashSet<&str> = lore_arch
let all_commodities: BTreeSet<&str> = lore_arch
.primary_commodities
.iter()
.chain(lore_arch.secondary_commodities.iter())
@@ -530,9 +522,9 @@ fn make_corp_id(name: &str) -> String {
// ---------------------------------------------------------------------------
struct CoverageReport {
commodity_coverage: HashMap<String, usize>,
commodity_coverage: BTreeMap<String, usize>,
uncovered_commodities: Vec<String>,
system_coverage: HashMap<String, usize>,
system_coverage: BTreeMap<String, usize>,
uncovered_systems: Vec<String>,
total_generated: usize,
}
@@ -540,17 +532,17 @@ struct CoverageReport {
fn validate_coverage(
generated: &BTreeMap<String, GeneratedCorp>,
lore_archetypes: &BTreeMap<String, LoreArchetype>,
commodity_ids: &HashSet<String>,
commodity_ids: &BTreeSet<String>,
conn: &Connection,
) -> CoverageReport {
// Track which commodities have at least one producer
let mut commodity_coverage: HashMap<String, usize> = HashMap::new();
let mut commodity_coverage: BTreeMap<String, usize> = BTreeMap::new();
for cid in commodity_ids {
commodity_coverage.insert(cid.clone(), 0);
}
// Track system presence
let mut system_coverage: HashMap<String, usize> = HashMap::new();
let mut system_coverage: BTreeMap<String, usize> = BTreeMap::new();
for corp in generated.values() {
// Count commodity coverage from lore archetype
@@ -593,22 +585,19 @@ fn validate_coverage(
// Also check body-level population since system_economy only has 10 systems > 100K
// but 146 bodies > 100K
let mut body_systems: HashSet<String> = HashSet::new();
let mut stmt2 = conn
.prepare(
"SELECT DISTINCT system_id FROM bodies
WHERE inhabited = 1 AND population > 100000",
)
.unwrap();
for row in stmt2
let body_systems: BTreeSet<String> = stmt2
.query_map([], |row| row.get::<_, String>(0))
.unwrap()
.filter_map(|r| r.ok())
{
body_systems.insert(row);
}
.collect();
let mut all_high_pop: HashSet<String> = high_pop_systems.into_iter().collect();
let mut all_high_pop: BTreeSet<String> = high_pop_systems.into_iter().collect();
all_high_pop.extend(body_systems);
let uncovered_systems: Vec<String> = all_high_pop
@@ -634,7 +623,7 @@ fn validate_coverage(
fn fill_coverage_gaps(
generated: &mut BTreeMap<String, GeneratedCorp>,
lore_archetypes: &BTreeMap<String, LoreArchetype>,
commodity_ids: &HashSet<String>,
commodity_ids: &BTreeSet<String>,
conn: &Connection,
rng: &mut ChaCha8Rng,
) {
@@ -679,21 +668,16 @@ fn fill_coverage_gaps(
let name = names::generate_name(rng, &sector, &lore.category);
let corp_id = make_corp_id(&name);
if !generated.contains_key(&corp_id) {
generated.insert(
corp_id,
GeneratedCorp {
proper_name: name,
lore_archetype: lore_id.to_string(),
behavioral_archetype: behavioral,
location_id: loc_id,
location_type: loc_type,
system_id: sys_id.clone(),
geographic_sector: sector,
brands: vec![],
},
);
}
generated.entry(corp_id).or_insert_with(|| GeneratedCorp {
proper_name: name,
lore_archetype: lore_id.to_string(),
behavioral_archetype: behavioral,
location_id: loc_id,
location_type: loc_type,
system_id: sys_id.clone(),
geographic_sector: sector,
brands: vec![],
});
}
}
@@ -757,41 +741,31 @@ fn fill_coverage_gaps(
for _ in current_count..3 {
let n = names::generate_name(rng, sector, &lore.category);
let cid = make_corp_id(&n);
if !generated.contains_key(&cid) {
generated.insert(
cid,
GeneratedCorp {
proper_name: n,
lore_archetype: arch_id.to_string(),
behavioral_archetype: pick_behavioral_archetype(
rng,
&lore.behavioral_affinity,
),
location_id: loc_id.clone(),
location_type: "body".to_string(),
system_id: sys_id.clone(),
geographic_sector: sector.to_string(),
brands: vec![],
},
);
}
generated.entry(cid).or_insert_with(|| GeneratedCorp {
proper_name: n,
lore_archetype: arch_id.to_string(),
behavioral_archetype: pick_behavioral_archetype(
rng,
&lore.behavioral_affinity,
),
location_id: loc_id.clone(),
location_type: "body".to_string(),
system_id: sys_id.clone(),
geographic_sector: sector.to_string(),
brands: vec![],
});
}
if !generated.contains_key(&corp_id) {
generated.insert(
corp_id,
GeneratedCorp {
proper_name: name,
lore_archetype: arch_id.to_string(),
behavioral_archetype: behavioral,
location_id: loc_id,
location_type: "body".to_string(),
system_id: sys_id,
geographic_sector: sector.to_string(),
brands: vec![],
},
);
}
generated.entry(corp_id).or_insert_with(|| GeneratedCorp {
proper_name: name,
lore_archetype: arch_id.to_string(),
behavioral_archetype: behavioral,
location_id: loc_id,
location_type: "body".to_string(),
system_id: sys_id,
geographic_sector: sector.to_string(),
brands: vec![],
});
}
}
}
@@ -983,7 +957,7 @@ fn main() {
report.system_coverage.len()
);
let mut by_sector: HashMap<String, usize> = HashMap::new();
let mut by_sector: BTreeMap<String, usize> = BTreeMap::new();
for corp in generated.values() {
*by_sector.entry(corp.geographic_sector.clone()).or_insert(0) += 1;
}