use std::collections::HashMap;
use std::sync::{LazyLock, Mutex};
use super::SettingSource;
use super::validation::{SettingsWithErrors, ValidationError};
#[derive(Debug, Clone, Default, PartialEq)]
pub struct ParsedSettings {
pub settings: Option<serde_json::Value>,
pub errors: Vec<ValidationError>,
}
struct SettingsCacheInner {
session_settings: Option<SettingsWithErrors>,
per_source_cache: HashMap<SettingSource, Option<serde_json::Value>>,
parse_file_cache: HashMap<String, ParsedSettings>,
plugin_settings_base: Option<serde_json::Value>,
}
static SETTINGS_CACHE: LazyLock<Mutex<SettingsCacheInner>> = LazyLock::new(|| {
Mutex::new(SettingsCacheInner {
session_settings: None,
per_source_cache: HashMap::new(),
parse_file_cache: HashMap::new(),
plugin_settings_base: None,
})
});
pub fn get_session_settings_cache() -> Option<SettingsWithErrors> {
SETTINGS_CACHE.lock().unwrap().session_settings.clone()
}
pub fn set_session_settings_cache(value: SettingsWithErrors) {
SETTINGS_CACHE.lock().unwrap().session_settings = Some(value);
}
pub fn get_cached_settings_for_source(
source: &SettingSource,
) -> Option<Option<serde_json::Value>> {
SETTINGS_CACHE
.lock()
.unwrap()
.per_source_cache
.get(source)
.cloned()
}
pub fn set_cached_settings_for_source(
source: &SettingSource,
value: Option<serde_json::Value>,
) {
let mut cache = SETTINGS_CACHE.lock().unwrap();
cache.per_source_cache.insert(source.clone(), value);
}
pub fn get_cached_parsed_file(path: &str) -> Option<ParsedSettings> {
SETTINGS_CACHE
.lock()
.unwrap()
.parse_file_cache
.get(path)
.cloned()
}
pub fn set_cached_parsed_file(path: &str, value: ParsedSettings) {
SETTINGS_CACHE
.lock()
.unwrap()
.parse_file_cache
.insert(path.to_string(), value);
}
pub fn get_plugin_settings_base() -> Option<serde_json::Value> {
SETTINGS_CACHE.lock().unwrap().plugin_settings_base.clone()
}
pub fn set_plugin_settings_base(value: Option<serde_json::Value>) {
SETTINGS_CACHE.lock().unwrap().plugin_settings_base = value;
}
pub fn clear_plugin_settings_base() {
SETTINGS_CACHE.lock().unwrap().plugin_settings_base = None;
}
pub fn reset_settings_cache() {
let mut cache = SETTINGS_CACHE.lock().unwrap();
cache.session_settings = None;
cache.per_source_cache.clear();
cache.parse_file_cache.clear();
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_session_cache_roundtrip() {
reset_settings_cache();
assert!(get_session_settings_cache().is_none());
let settings = SettingsWithErrors {
settings: serde_json::json!({"permissions": {"defaultMode": "allow"}}),
errors: vec![],
};
set_session_settings_cache(settings.clone());
assert_eq!(
get_session_settings_cache().as_ref(),
Some(&settings),
);
}
#[test]
fn test_per_source_cache() {
reset_settings_cache();
let source = SettingSource::UserSettings;
assert!(get_cached_settings_for_source(&source).is_none());
set_cached_settings_for_source(
&source,
Some(serde_json::json!({"permissions": {"defaultMode": "deny"}})),
);
assert!(get_cached_settings_for_source(&source).is_some());
set_cached_settings_for_source(&source, None);
assert!(get_cached_settings_for_source(&source).is_some());
assert!(get_cached_settings_for_source(&source).unwrap().is_none());
}
#[test]
fn test_parse_file_cache() {
reset_settings_cache();
assert!(get_cached_parsed_file("/nonexistent").is_none());
let parsed = ParsedSettings {
settings: Some(serde_json::json!({})),
errors: vec![],
};
set_cached_parsed_file("/test/path.json", parsed.clone());
assert_eq!(
get_cached_parsed_file("/test/path/path.json").as_ref(),
None,
);
assert_eq!(
get_cached_parsed_file("/test/path.json").as_ref(),
Some(&parsed),
);
}
#[test]
fn test_plugin_settings_base() {
reset_settings_cache();
assert!(get_plugin_settings_base().is_none());
set_plugin_settings_base(Some(serde_json::json!({"model": {"name": "test"}})));
assert!(get_plugin_settings_base().is_some());
clear_plugin_settings_base();
assert!(get_plugin_settings_base().is_none());
}
#[test]
fn test_reset_clears_all() {
set_session_settings_cache(SettingsWithErrors {
settings: serde_json::json!({}),
errors: vec![],
});
set_cached_settings_for_source(
&SettingSource::UserSettings,
Some(serde_json::json!({})),
);
set_cached_parsed_file(
"/test.json",
ParsedSettings {
settings: Some(serde_json::json!({})),
errors: vec![],
},
);
set_plugin_settings_base(Some(serde_json::json!({})));
reset_settings_cache();
assert!(get_session_settings_cache().is_none());
assert!(get_cached_settings_for_source(&SettingSource::UserSettings).is_none());
assert!(get_cached_parsed_file("/test.json").is_none());
}
}