use crate::config_types::{
ConfigError, ConfigSource, ConfigWatcher, ConfigurationManager, Environment, OxirsConfig,
PerformanceProfile,
};
use std::path::Path;
use std::sync::{Arc, RwLock};
impl ConfigurationManager {
pub fn new() -> Self {
Self {
config: Arc::new(RwLock::new(OxirsConfig::default())),
environment: Environment::Development,
config_sources: Vec::new(),
watchers: Vec::new(),
}
}
pub fn load_from_file<P: AsRef<Path>>(&mut self, path: P) -> Result<(), ConfigError> {
let content = std::fs::read_to_string(&path)
.map_err(|_| ConfigError::FileNotFound(path.as_ref().to_path_buf()))?;
let config: OxirsConfig = if path.as_ref().extension() == Some(std::ffi::OsStr::new("toml"))
{
toml::from_str(&content).map_err(|e| ConfigError::InvalidFormat(e.to_string()))?
} else {
serde_json::from_str(&content)?
};
self.update_config(config)?;
self.config_sources.push(ConfigSource::File {
path: path.as_ref().to_path_buf(),
});
Ok(())
}
pub fn load_from_environment(&mut self) -> Result<(), ConfigError> {
let mut config = self.get_config();
if let Ok(profile_str) = std::env::var("OXIRS_PERFORMANCE_PROFILE") {
if let Ok(profile) =
serde_json::from_str::<PerformanceProfile>(&format!("\"{}\"", profile_str))
{
config.performance.profile = profile;
}
}
if let Ok(threads_str) = std::env::var("OXIRS_THREAD_COUNT") {
if let Ok(threads) = threads_str.parse::<usize>() {
config.concurrency.thread_pool.worker_threads = threads;
}
}
self.update_config(config)?;
self.config_sources.push(ConfigSource::Environment);
Ok(())
}
pub fn get_config(&self) -> OxirsConfig {
self.config
.read()
.expect("config RwLock should not be poisoned")
.clone()
}
pub fn update_config(&mut self, new_config: OxirsConfig) -> Result<(), ConfigError> {
crate::config_validation::validate_config(&new_config)?;
*self
.config
.write()
.expect("config RwLock should not be poisoned") = new_config;
Ok(())
}
pub fn set_performance_profile(
&mut self,
profile: PerformanceProfile,
) -> Result<(), ConfigError> {
let mut config = self.get_config();
config.performance.profile = profile;
config.performance.custom_settings = profile.get_config();
self.update_config(config)
}
pub fn get_performance_profile(&self) -> PerformanceProfile {
self.get_config().performance.profile
}
pub fn add_watcher<F>(&mut self, source: ConfigSource, callback: F)
where
F: Fn(&OxirsConfig) + Send + Sync + 'static,
{
self.watchers.push(ConfigWatcher {
source,
callback: Box::new(callback),
});
}
pub async fn start_monitoring(&self) -> Result<(), ConfigError> {
Ok(())
}
}
impl Default for ConfigurationManager {
fn default() -> Self {
Self::new()
}
}