use std::{
collections::HashMap,
fs,
path::{Path, PathBuf},
};
use directories::ProjectDirs;
use itertools::Itertools;
use lib::Error;
use serde_json::Value;
use crate::{APPLICATION_NAME, configuration::GlobalConfig};
#[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(test, derive(schemars::JsonSchema))]
pub struct Workspace {
pub path: PathBuf,
pub(super) config: GlobalConfig,
log_file: PathBuf,
}
impl Default for Workspace {
fn default() -> Self {
Self {
path: Self::yozefu_directory().unwrap(),
config: GlobalConfig::new(
&Workspace::yozefu_directory()
.unwrap()
.join(Self::CONFIG_FILENAME),
),
log_file: Self::yozefu_directory().unwrap().join(Self::LOGS_FILENAME),
}
}
}
impl Workspace {
pub const CONFIG_FILENAME: &str = "config.json";
pub const LOGS_FILENAME: &str = "application.log";
pub const THEMES_FILENAME: &str = "themes.json";
pub const FILTERS_DIRECTORY: &str = "filters";
pub fn new(directory: &Path, config: GlobalConfig, log_file: PathBuf) -> Self {
Self {
path: directory.to_path_buf(),
config,
log_file,
}
}
fn yozefu_directory() -> Result<PathBuf, Error> {
ProjectDirs::from("io", "maif", APPLICATION_NAME)
.ok_or(Error::Error(
"Failed to find the yozefu configuration directory".to_string(),
))
.map(|e| e.config_dir().to_path_buf())
}
pub fn config_file(&self) -> PathBuf {
self.config.path.clone()
}
pub fn log_file(&self) -> PathBuf {
self.log_file.clone()
}
pub fn config(&self) -> &GlobalConfig {
&self.config
}
pub fn themes_file(&self) -> PathBuf {
self.path.join(Self::THEMES_FILENAME)
}
pub fn themes(&self) -> Vec<String> {
let file = self.themes_file();
let content = fs::read_to_string(file).unwrap_or("{}".to_string());
let themes: HashMap<String, Value> = serde_json::from_str(&content).unwrap_or_default();
themes
.keys()
.map(std::string::ToString::to_string)
.collect_vec()
}
pub fn filters_dir(&self) -> PathBuf {
let dir = self.path.join(Self::FILTERS_DIRECTORY);
let _ = fs::create_dir_all(&dir);
dir
}
}