use crate::library_manager::{LibraryConfig, with_library_manager, with_library_manager_mut};
use std::collections::HashMap;
#[derive(Debug, Clone, Default)]
pub struct Settings {
pub library_versions: HashMap<String, String>,
}
impl Settings {
pub fn new() -> Self {
let config = with_library_manager(|manager| manager.get_config().clone());
let mut library_versions = HashMap::new();
library_versions.insert("Substance Base".to_string(), config.substance_base.clone());
library_versions.insert(
"All Keys Substance".to_string(),
config.all_keys_substance.clone(),
);
library_versions.insert("Elements".to_string(), config.elements.clone());
library_versions.insert("Reactbase".to_string(), config.reactbase.clone());
library_versions.insert("Dict Reaction".to_string(), config.dict_reaction.clone());
library_versions.insert(
"Problems Folder".to_string(),
config.problems_folder.clone(),
);
Self { library_versions }
}
pub fn get_library_version(&self, library_name: &str) -> Option<&String> {
self.library_versions.get(library_name)
}
pub fn set_library_version(&mut self, library_name: &str, version: &str) -> Result<(), String> {
let result = with_library_manager_mut(|manager| match library_name {
"Substance Base" => manager.set_substance_base(version),
"All Keys Substance" => manager.set_all_keys_substance(version),
"Elements" => manager.set_elements(version),
"Reactbase" => manager.set_reactbase(version),
"Dict Reaction" => manager.set_dict_reaction(version),
"Problems Folder" => manager.set_problems_folder(version),
_ => Err(format!("Unknown library: {}", library_name).into()),
});
match result {
Ok(_) => {
self.library_versions
.insert(library_name.to_string(), version.to_string());
Ok(())
}
Err(e) => Err(e.to_string()),
}
}
pub fn get_available_libraries(&self) -> Vec<&String> {
self.library_versions.keys().collect()
}
pub fn reset_to_defaults(&mut self) -> Result<(), String> {
with_library_manager_mut(|manager| match manager.reset_to_defaults() {
Ok(_) => {
let config = manager.get_config();
self.library_versions.clear();
self.library_versions
.insert("Substance Base".to_string(), config.substance_base.clone());
self.library_versions.insert(
"All Keys Substance".to_string(),
config.all_keys_substance.clone(),
);
self.library_versions
.insert("Elements".to_string(), config.elements.clone());
self.library_versions
.insert("Reactbase".to_string(), config.reactbase.clone());
self.library_versions
.insert("Dict Reaction".to_string(), config.dict_reaction.clone());
self.library_versions.insert(
"Problems Folder".to_string(),
config.problems_folder.clone(),
);
Ok(())
}
Err(e) => Err(e.to_string()),
})
}
pub fn update_multiple_libraries(
&mut self,
updates: HashMap<&str, &str>,
) -> Result<(), String> {
let mut internal_updates = HashMap::new();
for (display_name, path) in &updates {
let internal_key = match *display_name {
"Substance Base" => "substance_base",
"All Keys Substance" => "all_keys_substance",
"Elements" => "elements",
"Reactbase" => "reactbase",
"Dict Reaction" => "dict_reaction",
"Problems Folder" => "problems_folder",
_ => return Err(format!("Unknown library: {}", display_name)),
};
internal_updates.insert(internal_key, *path);
}
with_library_manager_mut(|manager| {
match manager.update_libraries(internal_updates) {
Ok(_) => {
for (display_name, path) in updates {
self.library_versions
.insert(display_name.to_string(), path.to_string());
}
Ok(())
}
Err(e) => Err(e.to_string()),
}
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::library_manager::LibraryManager;
use std::io::Write;
use tempfile::NamedTempFile;
fn create_test_manager() -> LibraryManager {
let (substance_file, keys_file, elements_file, react_file, dict_file) = create_test_files();
let mut config_file = NamedTempFile::new().unwrap();
let config = LibraryConfig {
substance_base: substance_file.path().to_str().unwrap().to_string(),
all_keys_substance: keys_file.path().to_str().unwrap().to_string(),
elements: elements_file.path().to_str().unwrap().to_string(),
reactbase: react_file.path().to_str().unwrap().to_string(),
dict_reaction: dict_file.path().to_str().unwrap().to_string(),
problems_folder: "problems".to_string(),
};
let config_json = serde_json::to_string_pretty(&config).unwrap();
config_file.write_all(config_json.as_bytes()).unwrap();
LibraryManager::with_config_file(config_file.path().to_str().unwrap())
}
fn create_test_files() -> (
NamedTempFile,
NamedTempFile,
NamedTempFile,
NamedTempFile,
NamedTempFile,
) {
let mut substance_file = NamedTempFile::new().unwrap();
let mut keys_file = NamedTempFile::new().unwrap();
let mut elements_file = NamedTempFile::new().unwrap();
let mut react_file = NamedTempFile::new().unwrap();
let mut dict_file = NamedTempFile::new().unwrap();
substance_file.write_all(b"{}").unwrap();
keys_file.write_all(b"[]").unwrap();
elements_file.write_all(b"[]").unwrap();
react_file.write_all(b"{}").unwrap();
dict_file.write_all(b"{}").unwrap();
(
substance_file,
keys_file,
elements_file,
react_file,
dict_file,
)
}
#[test]
fn test_settings_new() {
crate::library_manager::set_test_manager(create_test_manager());
let settings = Settings::new();
assert_eq!(settings.library_versions.len(), 5);
assert!(settings.library_versions.contains_key("Substance Base"));
assert!(settings.library_versions.contains_key("All Keys Substance"));
assert!(settings.library_versions.contains_key("Reactbase"));
assert!(settings.library_versions.contains_key("Dict Reaction"));
assert!(settings.library_versions.contains_key("Problems Folder"));
crate::library_manager::clear_test_manager();
}
#[test]
fn test_get_library_version() {
crate::library_manager::set_test_manager(create_test_manager());
let settings = Settings::new();
let version = settings.get_library_version("Substance Base");
assert!(version.is_some());
crate::library_manager::clear_test_manager();
}
#[test]
fn test_set_library_version() {
crate::library_manager::set_test_manager(create_test_manager());
let mut temp_file = NamedTempFile::new().unwrap();
temp_file.write_all(b"{}").unwrap();
let mut settings = Settings::new();
let result =
settings.set_library_version("Substance Base", temp_file.path().to_str().unwrap());
assert!(result.is_ok());
assert_eq!(
settings.get_library_version("Substance Base").unwrap(),
temp_file.path().to_str().unwrap()
);
crate::library_manager::clear_test_manager();
}
#[test]
fn test_update_multiple_libraries() {
crate::library_manager::set_test_manager(create_test_manager());
let mut temp_file1 = NamedTempFile::new().unwrap();
let mut temp_file2 = NamedTempFile::new().unwrap();
temp_file1.write_all(b"{}").unwrap();
temp_file2.write_all(b"[]").unwrap();
let mut settings = Settings::new();
let mut updates = HashMap::new();
updates.insert("Substance Base", temp_file1.path().to_str().unwrap());
updates.insert("All Keys Substance", temp_file2.path().to_str().unwrap());
let result = settings.update_multiple_libraries(updates);
assert!(result.is_ok());
assert_eq!(
settings.get_library_version("Substance Base").unwrap(),
temp_file1.path().to_str().unwrap()
);
assert_eq!(
settings.get_library_version("All Keys Substance").unwrap(),
temp_file2.path().to_str().unwrap()
);
crate::library_manager::clear_test_manager();
}
}