use figment::{
providers::{Env, Format, Json, Toml, Yaml},
Figment,
};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub height: Option<u16>,
pub mouse_enabled: Option<bool>,
pub case_matching: Option<String>,
pub normalization: Option<String>,
pub wrap_around: Option<bool>,
pub invert_scroll: Option<bool>,
pub preview_command: Option<String>,
}
impl Default for Config {
fn default() -> Self {
Self {
height: None,
mouse_enabled: Some(true),
case_matching: Some("smart".to_string()),
normalization: Some("smart".to_string()),
wrap_around: Some(true),
invert_scroll: Some(false),
preview_command: None,
}
}
}
impl Config {
pub fn load() -> Result<Self, figment::Error> {
let mut figment = Figment::new();
if let Some(config_dir) = directories::ProjectDirs::from("", "", "picleo") {
if let Some(config_dir) = config_dir.config_dir().parent() {
let system_config = config_dir.join("picleo").join("config");
figment = Self::add_config_files(figment, &system_config);
}
let user_config = config_dir.config_dir().join("config");
figment = Self::add_config_files(figment, &user_config);
}
figment = Self::add_config_files(figment, &PathBuf::from(".picleo"));
figment = figment.merge(Env::prefixed("PICLEO_"));
figment.extract()
}
fn add_config_files(mut figment: Figment, base_path: &PathBuf) -> Figment {
for extension in &["toml", "yaml", "yml", "json"] {
let config_file = base_path.with_extension(extension);
if config_file.exists() {
figment = match extension {
&"toml" => figment.merge(Toml::file(config_file)),
&"yaml" | &"yml" => figment.merge(Yaml::file(config_file)),
&"json" => figment.merge(Json::file(config_file)),
_ => figment,
};
}
}
figment
}
pub fn height(&self) -> Option<u16> {
self.height
}
pub fn mouse_enabled(&self) -> bool {
self.mouse_enabled.unwrap_or(true)
}
pub fn wrap_around(&self) -> bool {
self.wrap_around.unwrap_or(true)
}
pub fn invert_scroll(&self) -> bool {
self.invert_scroll.unwrap_or(false)
}
pub fn preview_command(&self) -> Option<&String> {
self.preview_command.as_ref()
}
}