Skip to content

Commit 182e469

Browse files
graylikemeclaude
andcommitted
fix: add slug alias mapping to equipment seed for MegaMek names
MegaMek uses internal names like CLERLargeLaser/ISUltraAC5 that get slugified to clerlargelaser/isultraac5, while the seed JSON uses clean slugs like clan-er-large-laser/ultra-autocannon-5. Added a 48-entry alias table so the seed matches all 108 entries (previously 60). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 54e7d42 commit 182e469

1 file changed

Lines changed: 86 additions & 8 deletions

File tree

crates/scraper/src/equipment_seed.rs

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::collections::HashMap;
12
use std::path::Path;
23

34
use anyhow::Context;
@@ -20,6 +21,72 @@ pub struct EquipmentStats {
2021
pub bv: Option<i32>,
2122
}
2223

24+
/// Build a mapping from clean JSON slugs to MegaMek DB slugs.
25+
///
26+
/// MegaMek uses internal names like `CLERLargeLaser` or `ISUltraAC5` which get
27+
/// slugified to `clerlargelaser` / `isultraac5`. The JSON uses human-readable
28+
/// slugs like `clan-er-large-laser` / `ultra-autocannon-5`. This table bridges
29+
/// the two naming conventions.
30+
fn slug_aliases() -> HashMap<&'static str, &'static str> {
31+
HashMap::from([
32+
// Clan energy weapons
33+
("clan-er-large-laser", "clerlargelaser"),
34+
("clan-er-medium-laser", "clermediumlaser"),
35+
("clan-er-small-laser", "clersmalllaser"),
36+
("clan-er-ppc", "clerppc"),
37+
("clan-large-pulse-laser", "cllargepulselaser"),
38+
("clan-medium-pulse-laser", "clmediumpulselaser"),
39+
("clan-small-pulse-laser", "clsmallpulselaser"),
40+
("clan-er-flamer", "clerflamer"),
41+
("clan-plasma-cannon", "clplasmacannon"),
42+
// IS energy weapons (pulse)
43+
("pulse-large-laser", "islargepulselaser"),
44+
("pulse-medium-laser", "ismediumpulselaser"),
45+
("pulse-small-laser", "issmallpulselaser"),
46+
// IS ballistic weapons
47+
("ultra-autocannon-2", "isultraac2"),
48+
("ultra-autocannon-5", "isultraac5"),
49+
("ultra-autocannon-10", "isultraac10"),
50+
("ultra-autocannon-20", "isultraac20"),
51+
("rotary-autocannon-5", "isrotaryac5"),
52+
("light-autocannon-5", "light-ac-5"),
53+
// Clan ballistic weapons
54+
("clan-ultra-autocannon-2", "clultraac2"),
55+
("clan-ultra-autocannon-5", "clultraac5"),
56+
("clan-ultra-autocannon-10", "clultraac10"),
57+
("clan-ultra-autocannon-20", "clultraac20"),
58+
("clan-lb-2-x-ac", "cllbxac2"),
59+
("clan-lb-5-x-ac", "cllbxac5"),
60+
("clan-lb-10-x-ac", "cllbxac10"),
61+
("clan-lb-20-x-ac", "cllbxac20"),
62+
("clan-gauss-rifle", "clgaussrifle"),
63+
// Clan missile weapons
64+
("clan-srm-2", "clsrm2"),
65+
("clan-srm-4", "clsrm4"),
66+
("clan-srm-6", "clsrm6"),
67+
("clan-lrm-5", "cllrm5"),
68+
("clan-lrm-10", "cllrm10"),
69+
("clan-lrm-15", "cllrm15"),
70+
("clan-lrm-20", "cllrm20"),
71+
("clan-streak-srm-2", "clstreaksrm2"),
72+
("clan-streak-srm-4", "clstreaksrm4"),
73+
("clan-streak-srm-6", "clstreaksrm6"),
74+
("clan-arrow-iv", "clarrowiv"),
75+
// IS missile
76+
("narc-missile-beacon", "narc"),
77+
// Electronics / equipment
78+
("guardian-ecm-suite", "isguardianecmsuite"),
79+
("clan-ecm-suite", "clecmsuite"),
80+
("beagle-active-probe", "beagleactiveprobe"),
81+
("clan-active-probe", "clactiveprobe"),
82+
("clan-anti-missile-system","clantimissilesystem"),
83+
("targeting-computer", "istargeting-computer"),
84+
("artemis-iv-fcs", "isartemisiv"),
85+
("c3-master-computer", "isc3mastercomputer"),
86+
("c3-slave-unit", "isc3slaveunit"),
87+
])
88+
}
89+
2390
pub async fn run(file: &Path, database_url: &str, pool_size: u32, force: bool) -> anyhow::Result<()> {
2491
let pool = sqlx::postgres::PgPoolOptions::new()
2592
.max_connections(pool_size)
@@ -34,23 +101,37 @@ pub async fn run(file: &Path, database_url: &str, pool_size: u32, force: bool) -
34101

35102
info!(count = entries.len(), "loaded equipment stats entries");
36103

104+
let aliases = slug_aliases();
37105
let mut updated = 0u32;
38-
let skipped = 0u32;
39106
let mut not_found = 0u32;
40107
let mut unchanged = 0u32;
108+
let mut alias_hits = 0u32;
41109

42110
for entry in &entries {
43-
let exists = sqlx::query("SELECT id FROM equipment WHERE slug = $1")
111+
// Try exact slug match first, then alias fallback
112+
let mut row = sqlx::query("SELECT id FROM equipment WHERE slug = $1")
44113
.bind(&entry.slug)
45114
.fetch_optional(&pool)
46115
.await?;
47116

48-
let Some(row) = exists else {
117+
if row.is_none() {
118+
if let Some(&alt) = aliases.get(entry.slug.as_str()) {
119+
row = sqlx::query("SELECT id FROM equipment WHERE slug = $1")
120+
.bind(alt)
121+
.fetch_optional(&pool)
122+
.await?;
123+
if row.is_some() {
124+
alias_hits += 1;
125+
}
126+
}
127+
}
128+
129+
let Some(r) = row else {
49130
warn!(slug = %entry.slug, "no matching equipment row");
50131
not_found += 1;
51132
continue;
52133
};
53-
let eq_id: i32 = row.try_get("id")?;
134+
let eq_id: i32 = r.try_get("id")?;
54135

55136
if force {
56137
let result = sqlx::query(
@@ -129,14 +210,11 @@ pub async fn run(file: &Path, database_url: &str, pool_size: u32, force: bool) -
129210

130211
info!(
131212
updated,
132-
skipped,
213+
alias_hits,
133214
not_found,
134215
unchanged,
135216
"equipment seed complete"
136217
);
137218

138-
// Suppress unused variable warning
139-
let _ = skipped;
140-
141219
Ok(())
142220
}

0 commit comments

Comments
 (0)