1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use crate::app::style::Style;
use crate::args::Args;
use crate::widget::style::Color;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::fs;
use std::str::FromStr;
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct Config {
pub general: GeneralConfig,
pub gpg: GpgConfig,
}
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct GeneralConfig {
pub splash: bool,
pub tick_rate: u64,
pub color: String,
pub style: String,
pub file_explorer: String,
}
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct GpgConfig {
pub armor: bool,
pub homedir: Option<String>,
pub outdir: Option<String>,
pub default_key: Option<String>,
}
impl Config {
pub fn get_default_location() -> Option<String> {
if let Some(config_dir) = dirs_next::config_dir() {
let file_name = format!("{}.toml", env!("CARGO_PKG_NAME"));
for config_file in vec![
config_dir.join(&file_name),
config_dir.join(env!("CARGO_PKG_NAME")).join(&file_name),
config_dir.join(env!("CARGO_PKG_NAME")).join("config"),
] {
if config_file.exists() {
return config_file.to_str().map(String::from);
}
}
}
None
}
pub fn parse_config(file: &str) -> Result<Config> {
let contents = fs::read_to_string(file)?;
let config: Config = toml::from_str(&contents)?;
Ok(config)
}
pub fn update_args(self, mut args: Args) -> Args {
args.armor = self.gpg.armor;
args.splash = self.general.splash;
args.homedir = self.gpg.homedir;
args.outdir = self.gpg.outdir;
args.default_key = self.gpg.default_key;
args.tick_rate = self.general.tick_rate;
args.color = Color::from(self.general.color.as_ref());
args.style = Style::from_str(&self.general.style).unwrap_or_default();
args.file_explorer = self.general.file_explorer;
args
}
}
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
use std::path::PathBuf;
#[test]
fn test_parse_config() -> Result<()> {
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("config")
.join(format!("{}.toml", env!("CARGO_PKG_NAME")))
.to_string_lossy()
.into_owned();
if let Some(global_path) = Config::get_default_location() {
path = global_path;
}
let mut config = Config::parse_config(&path)?;
config.gpg.default_key = Some(String::from("test_key"));
let args = config.update_args(Args::default());
assert_eq!(Some(String::from("test_key")), args.default_key);
Ok(())
}
}