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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
use cursive::theme::{BaseColor, Color};
use directories::ProjectDirs;
use serde::{Deserialize, Serialize};
use std;
use std::default::Default;
use std::fs::{self, File, OpenOptions};
use std::io::{Read, Write};
use std::path::PathBuf;
pub const VIEW_WIDTH: usize = 25;
pub const VIEW_HEIGHT: usize = 8;
pub const GRID_WIDTH: usize = 3;
#[derive(Serialize, Deserialize)]
pub struct Characters {
#[serde(default = "base_char")]
pub true_chr: char,
#[serde(default = "base_char")]
pub false_chr: char,
#[serde(default = "base_char")]
pub future_chr: char,
}
fn base_char() -> char {
'·'
}
impl Default for Characters {
fn default() -> Self {
Characters {
true_chr: '·',
false_chr: '·',
future_chr: '·',
}
}
}
#[derive(Serialize, Deserialize)]
pub struct Colors {
#[serde(default = "cyan")]
pub reached: String,
#[serde(default = "magenta")]
pub todo: String,
#[serde(default = "light_black")]
pub inactive: String,
}
fn cyan() -> String {
"cyan".into()
}
fn magenta() -> String {
"magenta".into()
}
fn light_black() -> String {
"light black".into()
}
impl Default for Colors {
fn default() -> Self {
Colors {
reached: cyan(),
todo: magenta(),
inactive: light_black(),
}
}
}
#[derive(Serialize, Deserialize)]
pub struct AppConfig {
#[serde(default)]
pub look: Characters,
#[serde(default)]
pub colors: Colors,
}
impl Default for AppConfig {
fn default() -> Self {
AppConfig {
look: Default::default(),
colors: Default::default(),
}
}
}
impl AppConfig {
// TODO: implement string parsing from config.json
pub fn reached_color(&self) -> Color {
return Color::parse(&self.colors.reached).unwrap_or(Color::Dark(BaseColor::Cyan));
}
pub fn todo_color(&self) -> Color {
return Color::parse(&self.colors.todo).unwrap_or(Color::Dark(BaseColor::Magenta));
}
pub fn inactive_color(&self) -> Color {
return Color::parse(&self.colors.inactive).unwrap_or(Color::Light(BaseColor::Black));
}
}
pub fn load_configuration_file() -> AppConfig {
let cf = config_file();
if let Ok(ref mut f) = File::open(&cf) {
let mut j = String::new();
f.read_to_string(&mut j);
return toml::from_str(&j).unwrap_or_else(|e| panic!("Invalid config file: `{}`", e));
} else {
if let Ok(dc) = toml::to_string(&AppConfig::default()) {
match OpenOptions::new().create(true).write(true).open(&cf) {
Ok(ref mut file) => file.write(dc.as_bytes()).unwrap(),
Err(_) => panic!("Unable to write config file to disk!"),
};
}
return Default::default();
}
}
fn project_dirs() -> ProjectDirs {
ProjectDirs::from("rs", "nerdypepper", "dijo")
.unwrap_or_else(|| panic!("Invalid home directory!"))
}
pub fn config_file() -> PathBuf {
let proj_dirs = project_dirs();
let mut data_file = PathBuf::from(proj_dirs.config_dir());
fs::create_dir_all(&data_file);
data_file.push("config.toml");
return data_file;
}
pub fn habit_file() -> PathBuf {
let proj_dirs = project_dirs();
let mut data_file = PathBuf::from(proj_dirs.data_dir());
fs::create_dir_all(&data_file);
data_file.push("habit_record.json");
return data_file;
}
pub fn auto_habit_file() -> PathBuf {
let proj_dirs = project_dirs();
let mut data_file = PathBuf::from(proj_dirs.data_dir());
fs::create_dir_all(&data_file);
data_file.push("habit_record[auto].json");
return data_file;
}
|