use std::path::{Path, PathBuf};
use serde_repr::{Deserialize_repr, Serialize_repr};
#[derive(Serialize_repr, Deserialize_repr, Clone, Debug)]
#[repr(u16)]
pub enum BaseDirectory {
Audio = 1,
Cache,
Config,
Data,
LocalData,
Desktop,
Document,
Download,
Executable,
Font,
Home,
Picture,
Public,
Runtime,
Template,
Video,
Resource,
App,
}
pub fn resolve_path<P: AsRef<Path>>(path: P, dir: Option<BaseDirectory>) -> crate::Result<PathBuf> {
if let Some(base_dir) = dir {
let base_dir_path = match base_dir {
BaseDirectory::Audio => audio_dir(),
BaseDirectory::Cache => cache_dir(),
BaseDirectory::Config => config_dir(),
BaseDirectory::Data => data_dir(),
BaseDirectory::LocalData => local_data_dir(),
BaseDirectory::Desktop => desktop_dir(),
BaseDirectory::Document => document_dir(),
BaseDirectory::Download => download_dir(),
BaseDirectory::Executable => executable_dir(),
BaseDirectory::Font => font_dir(),
BaseDirectory::Home => home_dir(),
BaseDirectory::Picture => picture_dir(),
BaseDirectory::Public => public_dir(),
BaseDirectory::Runtime => runtime_dir(),
BaseDirectory::Template => template_dir(),
BaseDirectory::Video => video_dir(),
BaseDirectory::Resource => resource_dir(),
BaseDirectory::App => app_dir(),
};
if let Some(mut base_dir_path_value) = base_dir_path {
base_dir_path_value.push(path);
Ok(base_dir_path_value)
} else {
Err(crate::Error::Path("unable to determine base dir path".to_string()).into())
}
} else {
let mut dir_path = PathBuf::new();
dir_path.push(path);
Ok(dir_path)
}
}
pub fn audio_dir() -> Option<PathBuf> {
dirs_next::audio_dir()
}
pub fn cache_dir() -> Option<PathBuf> {
dirs_next::cache_dir()
}
pub fn config_dir() -> Option<PathBuf> {
dirs_next::config_dir()
}
pub fn data_dir() -> Option<PathBuf> {
dirs_next::data_dir()
}
pub fn local_data_dir() -> Option<PathBuf> {
dirs_next::data_local_dir()
}
pub fn desktop_dir() -> Option<PathBuf> {
dirs_next::desktop_dir()
}
pub fn document_dir() -> Option<PathBuf> {
dirs_next::document_dir()
}
pub fn download_dir() -> Option<PathBuf> {
dirs_next::download_dir()
}
pub fn executable_dir() -> Option<PathBuf> {
dirs_next::executable_dir()
}
pub fn font_dir() -> Option<PathBuf> {
dirs_next::font_dir()
}
pub fn home_dir() -> Option<PathBuf> {
dirs_next::home_dir()
}
pub fn picture_dir() -> Option<PathBuf> {
dirs_next::picture_dir()
}
pub fn public_dir() -> Option<PathBuf> {
dirs_next::public_dir()
}
pub fn runtime_dir() -> Option<PathBuf> {
dirs_next::runtime_dir()
}
pub fn template_dir() -> Option<PathBuf> {
dirs_next::template_dir()
}
pub fn video_dir() -> Option<PathBuf> {
dirs_next::video_dir()
}
pub fn resource_dir() -> Option<PathBuf> {
crate::platform::resource_dir().ok()
}
fn app_name() -> crate::Result<String> {
let exe = std::env::current_exe()?;
let app_name = exe
.file_name()
.expect("failed to get exe filename")
.to_string_lossy();
Ok(app_name.to_string())
}
pub fn app_dir() -> Option<PathBuf> {
dirs_next::config_dir().and_then(|mut dir| {
if let Ok(app_name) = app_name() {
dir.push(app_name);
Some(dir)
} else {
None
}
})
}