game_manager_lib/utils/
series.rs1use crate::utils::text::{contains_word_boundary, normalize_for_matching};
7use std::sync::OnceLock;
8
9fn get_known_series() -> &'static Vec<String> {
11 static SERIES_CACHE: OnceLock<Vec<String>> = OnceLock::new();
12 SERIES_CACHE.get_or_init(|| {
13 let json_content = include_str!("../data/known_series.json");
14 let mut list: Vec<String> =
15 serde_json::from_str(json_content).expect("Erro ao carregar known_series.json");
16 list.sort_by_key(|b| std::cmp::Reverse(b.len()));
18 list
19 })
20}
21
22pub fn infer_series(game_name: &str) -> Option<String> {
24 let normalized_target = normalize_for_matching(game_name);
25 let known_list = get_known_series();
26
27 for series in known_list {
29 let normalized_series = normalize_for_matching(&series);
30 if contains_word_boundary(&normalized_target, &normalized_series) {
31 return Some(series.clone());
32 }
33 }
34
35 let splitters = [":", " -", " –"];
38 for pattern in splitters {
39 if let Some(pos) = game_name.find(pattern) {
40 let base = game_name[..pos].trim();
41 if base.len() >= 3 {
42 return Some(base.to_string());
43 }
44 }
45 }
46
47 None
48}