use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct SectionNameDict {
name_to_id: HashMap<&'static str, &'static str>,
id_to_name: HashMap<&'static str, &'static str>,
}
impl SectionNameDict {
pub fn new() -> Self {
let mut name_to_id = HashMap::new();
let mut id_to_name = HashMap::new();
let mut add = |name: &'static str, id: &'static str| {
name_to_id.insert(name, id);
id_to_name.insert(id, name);
};
add("config", "c");
add("forge", "f");
add("stack", "k");
add("style", "y");
add("ui", "u");
add("media", "m");
add("i18n", "i");
add("icon", "o");
add("font", "t");
add("driven", "d");
add("generator", "g");
add("scripts", "s");
add("dependencies", "x");
add("js", "j");
add("python", "p");
add("rust", "r");
Self {
name_to_id,
id_to_name,
}
}
pub fn name_to_id(&self, name: &str) -> String {
self.name_to_id
.get(name)
.map(|s| s.to_string())
.unwrap_or_else(|| name.to_string())
}
pub fn id_to_name(&self, id: &str) -> String {
self.id_to_name
.get(id)
.map(|s| s.to_string())
.unwrap_or_else(|| id.to_string())
}
pub fn has_name(&self, name: &str) -> bool {
self.name_to_id.contains_key(name)
}
pub fn has_id(&self, id: &str) -> bool {
self.id_to_name.contains_key(id)
}
pub fn len(&self) -> usize {
self.name_to_id.len()
}
pub fn is_empty(&self) -> bool {
self.name_to_id.is_empty()
}
}
impl Default for SectionNameDict {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_section_name_dict_has_all_mappings() {
let dict = SectionNameDict::new();
assert_eq!(dict.len(), 16, "Should have 16 section mappings");
}
#[test]
fn test_name_to_id() {
let dict = SectionNameDict::new();
assert_eq!(dict.name_to_id("config"), "c");
assert_eq!(dict.name_to_id("forge"), "f");
assert_eq!(dict.name_to_id("stack"), "k");
assert_eq!(dict.name_to_id("style"), "y");
assert_eq!(dict.name_to_id("ui"), "u");
assert_eq!(dict.name_to_id("media"), "m");
assert_eq!(dict.name_to_id("i18n"), "i");
assert_eq!(dict.name_to_id("icon"), "o");
assert_eq!(dict.name_to_id("font"), "t");
assert_eq!(dict.name_to_id("driven"), "d");
assert_eq!(dict.name_to_id("generator"), "g");
assert_eq!(dict.name_to_id("scripts"), "s");
assert_eq!(dict.name_to_id("dependencies"), "x");
assert_eq!(dict.name_to_id("js"), "j");
assert_eq!(dict.name_to_id("python"), "p");
assert_eq!(dict.name_to_id("rust"), "r");
}
#[test]
fn test_id_to_name() {
let dict = SectionNameDict::new();
assert_eq!(dict.id_to_name("c"), "config");
assert_eq!(dict.id_to_name("f"), "forge");
assert_eq!(dict.id_to_name("k"), "stack");
assert_eq!(dict.id_to_name("y"), "style");
assert_eq!(dict.id_to_name("u"), "ui");
assert_eq!(dict.id_to_name("m"), "media");
assert_eq!(dict.id_to_name("i"), "i18n");
assert_eq!(dict.id_to_name("o"), "icon");
assert_eq!(dict.id_to_name("t"), "font");
assert_eq!(dict.id_to_name("d"), "driven");
assert_eq!(dict.id_to_name("g"), "generator");
assert_eq!(dict.id_to_name("s"), "scripts");
assert_eq!(dict.id_to_name("x"), "dependencies");
assert_eq!(dict.id_to_name("j"), "js");
assert_eq!(dict.id_to_name("p"), "python");
assert_eq!(dict.id_to_name("r"), "rust");
}
#[test]
fn test_unknown_passthrough() {
let dict = SectionNameDict::new();
assert_eq!(dict.name_to_id("unknown"), "unknown");
assert_eq!(dict.name_to_id("custom_section"), "custom_section");
assert_eq!(dict.id_to_name("z"), "z");
assert_eq!(dict.id_to_name("custom"), "custom");
}
#[test]
fn test_round_trip() {
let dict = SectionNameDict::new();
let names = [
"config",
"forge",
"stack",
"style",
"ui",
"media",
"i18n",
"icon",
"font",
"driven",
"generator",
"scripts",
"dependencies",
"js",
"python",
"rust",
];
for name in names {
let id = dict.name_to_id(name);
let back = dict.id_to_name(&id);
assert_eq!(back, name, "Round-trip failed for {}", name);
}
}
#[test]
fn test_has_name_and_id() {
let dict = SectionNameDict::new();
assert!(dict.has_name("forge"));
assert!(dict.has_name("style"));
assert!(!dict.has_name("unknown"));
assert!(dict.has_id("f"));
assert!(dict.has_id("y"));
assert!(!dict.has_id("z"));
}
}