use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
use std::sync::Mutex;
static METADATA_CACHE: Lazy<Mutex<HashMap<String, HashMap<String, HashMap<String, String>>>>> =
Lazy::new(|| Mutex::new(HashMap::new()));
#[derive(Serialize, Deserialize)]
struct EnumMetadata {
variants: HashMap<String, HashMap<String, String>>,
}
fn get_metadata_path(name: &str) -> PathBuf {
let mut path = PathBuf::from("target/tyzen/metadata");
path.push(format!("{}.json", name));
path
}
pub fn save_enum_metadata(name: &str, variants: &[(String, Vec<(String, String)>)]) {
let mut map = HashMap::new();
for (v_name, attrs) in variants {
let attrs_map: HashMap<_, _> = attrs.iter().cloned().collect();
map.insert(v_name.clone(), attrs_map);
}
if let Ok(mut cache) = METADATA_CACHE.lock() {
cache.insert(name.to_string(), map.clone());
}
let meta = EnumMetadata { variants: map };
let path = get_metadata_path(name);
if let Some(parent) = path.parent() {
let _ = fs::create_dir_all(parent);
}
if let Ok(json) = serde_json::to_string_pretty(&meta) {
let _ = fs::write(path, json);
}
}
pub fn load_enum_metadata(name: &str) -> Option<HashMap<String, HashMap<String, String>>> {
if let Ok(cache) = METADATA_CACHE.lock() {
if let Some(meta) = cache.get(name) {
return Some(meta.clone());
}
}
let path = get_metadata_path(name);
let content = fs::read_to_string(path).ok()?;
let meta: EnumMetadata = serde_json::from_str(&content).ok()?;
if let Ok(mut cache) = METADATA_CACHE.lock() {
cache.insert(name.to_string(), meta.variants.clone());
}
Some(meta.variants)
}