use crate::{MyResult, WSError, ENVIRON};
use serde::{Deserialize, Serialize};
use std::{
fs::{self, File},
io::{BufReader, BufWriter, Write},
path::{Path, PathBuf},
};
#[derive(Debug, Serialize, Deserialize)]
pub struct Config {
pub interval: u64,
pub min_dimension: u32,
pub wallpaper: PathBuf,
pub desktop: String,
pub dirs: Vec<String>,
}
impl Default for Config {
fn default() -> Self {
let interval: u64 = 30 * 60; let min_dimension: u32 = 800; let home = ENVIRON.get_home();
let figures = format!("{home}/Figures");
let images = format!("{home}/Images");
let wallpapers = format!("{home}/Wallpapers");
let pictures = format!("{home}/Pictures");
let imagens = format!("{home}/Imagens");
let pkg_name = ENVIRON.get_pkg_name();
let mut wallpaper: PathBuf = [home, pkg_name].iter().collect();
wallpaper.set_extension("jpg");
let dirs: Vec<String> = [
&figures,
&images,
&wallpapers,
&pictures,
&imagens,
"/usr/share/wallpapers",
"/usr/share/backgrounds",
"/usr/share/antergos/wallpapers",
"/tmp/teste",
]
.iter()
.map(ToString::to_string)
.collect();
Config {
interval,
min_dimension,
wallpaper,
desktop: ENVIRON.desktop.to_string(),
dirs,
}
}
}
impl Config {
pub fn new() -> MyResult<Self> {
let config_path: PathBuf = get_config_path()?;
let mut config: Config = match read_config_file(&config_path) {
Ok(configuration) => configuration,
Err(_) => {
eprintln!("Create the configuration file: {config_path:#?}\n");
Self::default()
}
};
config.desktop = ENVIRON.desktop.to_string(); config.write_config_file(&config_path)?;
Ok(config)
}
pub fn write_config_file(&self, path: &PathBuf) -> MyResult<()> {
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?
};
let file: File = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.truncate(true)
.open(path)
.map_err(|error| {
eprintln!("Failed to create file {path:?}");
eprintln!("Perhaps lack of permission!");
error
})?;
let mut writer = BufWriter::new(file);
serde_json::to_writer_pretty(&mut writer, &self)?;
writer.flush()?;
Ok(())
}
fn limits(&self) -> Self {
Config {
interval: 5,
min_dimension: 10,
..Config::default()
}
}
pub fn is_valid(&self) -> Result<(), WSError> {
let limits = self.limits();
if self.interval < limits.interval {
return Err(WSError::IntervalError(self.interval));
}
if self.min_dimension < limits.min_dimension {
return Err(WSError::DimensionError(self.min_dimension));
}
if let Some(parent) = self.wallpaper.parent() {
if !parent.exists() {
return Err(WSError::ParentError(parent.to_path_buf()));
}
}
Ok(())
}
}
fn get_config_path() -> MyResult<PathBuf> {
let home = ENVIRON.get_home();
let hidden_dir = ".config";
let pkg_name = ENVIRON.get_pkg_name();
let mut config_path: PathBuf = [home, hidden_dir, pkg_name, pkg_name].iter().collect();
config_path.set_extension("json");
Ok(config_path)
}
pub fn read_config_file<P>(path: P) -> MyResult<Config>
where
P: AsRef<Path>,
{
let file = File::open(path)?;
let reader = BufReader::new(file);
let config: Config = serde_json::from_reader(reader)?;
config.is_valid().map_err(|error| {
eprintln!("{error}");
error
})?;
Ok(config)
}