use std::{env, fmt};
use derive_getters::Getters;
use log::warn;
use once_cell::sync::Lazy;
use serde::Deserialize;
use crate::error::VsmRuntimeFault;
#[derive(Deserialize, Debug, Getters)]
pub struct Variables {
home: String,
vim_sessions: String,
}
impl fmt::Display for Variables {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Users home directory: {}\nVim session file location: {}",
self.home(),
self.vim_sessions()
)
}
}
impl Default for Variables {
fn default() -> Self {
env::var("HOME").map_or_else(
|_| Self {
home: "~/".to_owned(),
vim_sessions: "~/.config/vim_sessions".to_owned(),
},
|h| Self {
home: h.clone(),
vim_sessions: format!("{}/.config/vim_sessions", h),
},
)
}
}
#[derive(Deserialize, Debug, Getters)]
pub struct Paths {
vsm_config_dir: String,
vsm_config_file: String,
}
impl fmt::Display for Paths {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Vsm config dir: {}\nVsm config file location: {}",
self.vsm_config_dir(),
self.vsm_config_file(),
)
}
}
impl Default for Paths {
fn default() -> Self {
let config_dir = format!("{}/.config/vsm", Variables::default().home());
Self {
vsm_config_dir: config_dir.clone(),
vsm_config_file: format!("{}/config.toml", config_dir),
}
}
}
#[derive(Deserialize, Debug, Default, Getters)]
pub struct Environment {
var: Variables,
path: Paths,
}
impl Environment {
pub fn new() -> Result<Self, VsmRuntimeFault> {
envy::from_env::<Variables>().map_or_else(
|_| {
Err(VsmRuntimeFault::EnvironmentVariable {
msg: String::from("VIM_SESSIONS is not defined"),
})
},
|var| {
Ok(Self {
var,
path: Paths::default(),
})
},
)
}
}
pub static ENVIRONMENT: Lazy<Environment> = Lazy::new(|| {
Environment::new().unwrap_or_else(|e| {
warn!("{}", e);
warn!("Defaulting to {}", Variables::default().vim_sessions);
Environment::default()
})
});
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
use super::{Environment, Variables};
#[test]
fn test_create_env_config() {
let env_vars = Variables {
home: "~/".to_owned(),
vim_sessions: "~/.config/vim_sessions".to_owned(),
};
assert_eq!(env_vars.vim_sessions(), "~/.config/vim_sessions");
assert_eq!(env_vars.home(), "~/");
}
#[test]
fn test_create_root_config() {
let home = std::env::var("HOME").expect("Users $HOME is not defined");
let env = Environment::new().unwrap_or_default();
assert_eq!(
env.var().vim_sessions(),
&format!("{}/.config/vim_sessions", home)
);
assert_eq!(env.var().home(), &home);
}
}