use lazy_static::lazy_static;
use regex::Regex;
use std::collections::HashMap;
lazy_static! {
static ref RE_COMMON: Regex = Regex::new(r"(?i)\b(Games|Corp|Inc|Ltd|Co|Corporation|Industries|Elc|S\.R\.L|S\.A|inc|of America|Japan|UK|USA|Europe|do Brasil|du Canada|Canada|America|Austria|of)\b\.?").unwrap();
static ref RE_PUNCTUATION: Regex = Regex::new(r"[.,?]+$|-$").unwrap();
static ref NEEDS_CLEANING: Regex = Regex::new(r"[\(/,?]|(Games|Corp|Inc|Ltd|Co|Corporation|Industries|Elc|S\.R\.L|S\.A|inc|of America|Japan|UK|USA|Europe|do Brasil|du Canada|Canada|America|Austria|of)").unwrap();
}
const SUBSTITUTIONS_ARRAY: &[(&str, &str)] = &[
("1P", "Single-player game"),
("2P alt", "Alternate two-player mode"),
("2P sim", "Simultaneous two-player mode"),
("3P alt", "Alternate three-player mode"),
("3P sim", "Simultaneous three-player mode"),
("4P alt", "Alternate four-player mode"),
("4P sim", "Simultaneous four-player mode"),
("5P alt", "Alternate five-player mode"),
("6P alt", "Alternate six-player mode"),
("6P sim", "Simultaneous six-player mode"),
("8P alt", "Alternate eight-player mode"),
("8P sim", "Simultaneous eight-player mode"),
("9P alt", "Alternate nine-player mode"),
("???", "Unknown or unspecified number of players"),
("BIOS", "BIOS"),
("Device", "Non-playable device"),
("Non-arcade", "Non-arcade game"),
];
pub(crate) fn normalize_machine_name(description: &Option<String>) -> String {
if description.is_none() {
return String::new();
}
let step1 = description
.as_ref()
.unwrap()
.replace('?', "")
.replace("&", "&");
let step2: String = step1.split('(').next().unwrap_or("").to_string();
let mut result = String::new();
let mut capitalize_next = true;
for c in step2.chars() {
if c.is_whitespace() {
capitalize_next = true;
result.push(c);
} else if capitalize_next {
result.push(c.to_uppercase().next().unwrap());
capitalize_next = false;
} else {
result.push(c);
}
}
result
}
pub(crate) fn normalize_manufacturer_name(manufacturer: &Option<String>) -> String {
let parts: Vec<&str> = manufacturer
.as_ref()
.unwrap()
.trim()
.split(&['(', '/'][..])
.collect();
let mut result = parts[0].to_string();
if result.is_empty() && parts.len() > 1 {
result = parts[1].to_string();
}
if NEEDS_CLEANING.is_match(&result) {
result = RE_COMMON.replace_all(&result, "").to_string();
result = RE_PUNCTUATION.replace_all(&result, "").to_string();
}
result = result.replace('?', "").replace(',', "");
result = result.replace("<unknown>", "Unknown");
result = result.trim().to_string();
result
}
fn get_substitutions() -> HashMap<&'static str, &'static str> {
SUBSTITUTIONS_ARRAY.iter().cloned().collect()
}
pub(crate) fn normalize_nplayer_name(nplayers: &Option<String>) -> String {
let substitutions = get_substitutions();
nplayers
.as_ref()
.unwrap_or(&"Unknown".to_string())
.split('/')
.map(|part| {
let part = part.trim();
substitutions.get(part).unwrap_or(&part).to_string()
})
.collect::<Vec<_>>()
.join(", ")
}