use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::sync::Mutex;
use crate::ports::config_store::{ConfigStore, ConfigStoreError};
pub struct FakeConfigStore {
files: Mutex<HashMap<PathBuf, String>>,
write_calls: Mutex<Vec<(PathBuf, String)>>,
fail_on_write: Mutex<Option<String>>,
}
impl Default for FakeConfigStore {
fn default() -> Self {
Self::new()
}
}
impl FakeConfigStore {
pub fn new() -> Self {
Self {
files: Mutex::new(HashMap::new()),
write_calls: Mutex::new(Vec::new()),
fail_on_write: Mutex::new(None),
}
}
pub fn with_content(self, path: &Path, content: &str) -> Self {
self.files
.lock()
.unwrap_or_else(|e| e.into_inner())
.insert(path.to_path_buf(), content.to_string());
self
}
pub fn write_fails_with(self, msg: &str) -> Self {
*self.fail_on_write.lock().unwrap_or_else(|e| e.into_inner()) = Some(msg.to_string());
self
}
pub fn write_calls(&self) -> Vec<(PathBuf, String)> {
self.write_calls
.lock()
.unwrap_or_else(|e| e.into_inner())
.clone()
}
pub fn content(&self, path: &Path) -> Option<String> {
self.files
.lock()
.unwrap_or_else(|e| e.into_inner())
.get(path)
.cloned()
}
}
impl ConfigStore for FakeConfigStore {
fn read(&self, path: &Path) -> Result<Option<String>, ConfigStoreError> {
Ok(self
.files
.lock()
.unwrap_or_else(|e| e.into_inner())
.get(path)
.cloned())
}
fn write(&self, path: &Path, content: &str) -> Result<(), ConfigStoreError> {
if let Some(msg) = self
.fail_on_write
.lock()
.unwrap_or_else(|e| e.into_inner())
.as_ref()
{
return Err(ConfigStoreError::Write {
path: path.to_path_buf(),
source: std::io::Error::new(std::io::ErrorKind::PermissionDenied, msg.clone()),
});
}
self.write_calls
.lock()
.unwrap_or_else(|e| e.into_inner())
.push((path.to_path_buf(), content.to_string()));
self.files
.lock()
.unwrap_or_else(|e| e.into_inner())
.insert(path.to_path_buf(), content.to_string());
Ok(())
}
}