use std::{
convert::From,
env,
error::Error,
fs,
io::Error as IoError,
path::{Path, PathBuf},
str::Utf8Error,
string::String,
};
use serde::{de, ser, Deserialize, Serialize};
mod cache;
pub use cache::CacheFile;
mod config;
pub use config::ConfigFile;
mod data;
pub use data::DataFile;
mod state;
pub use state::StateFile;
#[inline]
pub(crate) fn load_home_env() -> PathBuf {
let mut path =
PathBuf::from(env::var("HOME").expect("unable to read environment variable '$HOME'"));
if path.is_relative() || path.as_os_str().is_empty() {
panic!("'$HOME' is relative instead of absolute");
}
path
}
#[inline]
pub(crate) fn home_path(
home_path_env: &str,
fallback: &str,
app_dir_name: &str,
filename: &str,
) -> PathBuf {
let mut path = if let Ok(path) = env::var(home_path_env) {
if !path.starts_with("/") {
let mut path = load_home_env();
path.push(fallback);
path
} else {
PathBuf::from(path)
}
} else {
let mut path = load_home_env();
path.push(fallback);
path
};
path.push(app_dir_name);
path.push(filename);
path
}
#[inline]
pub(crate) fn system_paths(
system_path_env: &str,
fallback: &str,
app_dir_name: &str,
filename: &str,
) -> Vec<PathBuf> {
let paths = if let Ok(paths) = env::var(system_path_env) {
paths
} else {
fallback.to_string()
};
let mut paths: Vec<PathBuf> = paths
.split(":")
.filter_map(|path| {
let path = PathBuf::from(path);
if path.is_absolute() {
Some(path)
} else {
None
}
})
.collect();
let mut iter = paths.iter_mut();
while let Some(path) = iter.next() {
path.push(app_dir_name);
path.push(filename);
}
paths
}
pub(crate) fn save_to_path<T: Serialize, E: Error + From<IoError>>(
obj: &T,
path: impl AsRef<Path>,
create_dirs: bool,
) -> Result<(), E> {
let path = path.as_ref();
if let Some(parent) = path.parent() {
if !path.is_dir() && create_dirs {
fs::create_dir_all(parent)?;
}
}
Ok(())
}
pub(crate) fn load_from_path<'a, T: Deserialize<'a>, E: Error + From<IoError>>(
path: impl AsRef<Path>,
) -> Result<T, E> {
let path = path.as_ref();
let data = fs::read_to_string(path)?;
todo!()
}
pub(crate) fn load_all_from_path<'a, T: Deserialize<'a>, E: Error + From<IoError>>(
path: impl AsRef<Path>,
) -> Result<Vec<T>, E> {
let path = path.as_ref();
todo!()
}