1use serde::{Deserialize, Serialize};
2use std::{fs::OpenOptions, io::Write, path::PathBuf};
3
4#[derive(Default, Serialize, Deserialize)]
5pub struct Config {
6 pub preferences: Preferences,
7 pub ui: UiConfig,
8}
9
10impl Config {
11 pub fn filename() -> String {
12 ".quartz.toml".to_string()
13 }
14
15 pub fn filepath() -> PathBuf {
16 let home = std::env::var("HOME").unwrap();
17 let mut path = PathBuf::new();
18
19 path.push(home);
20 path.push(Config::filename());
21
22 path
23 }
24
25 pub fn parse() -> Self {
26 let filepath = Config::filepath();
27
28 if let Ok(config_toml) = std::fs::read_to_string(filepath) {
29 return toml::from_str::<Config>(&config_toml).unwrap_or_default();
30 }
31
32 Config::default()
33 }
34
35 pub fn write(&mut self) -> Result<(), Box<dyn std::error::Error>> {
36 let content = toml::to_string(self)?;
37
38 let mut file = OpenOptions::new()
39 .create(true)
40 .write(true)
41 .truncate(true)
42 .open(Self::filepath())?;
43
44 file.write_all(content.as_bytes())?;
45
46 Ok(())
47 }
48}
49
50#[derive(Serialize, Default, Deserialize)]
51pub struct Preferences {
52 editor: Option<String>,
53 pager: Option<String>,
54}
55
56impl Preferences {
57 pub fn editor(&self) -> String {
58 if let Some(editor) = &self.editor {
59 editor.to_owned()
60 } else if let Ok(editor) = std::env::var("EDITOR") {
61 editor
62 } else {
63 "vim".to_string()
64 }
65 }
66
67 pub fn set_editor<T>(&mut self, editor: T)
68 where
69 T: Into<String>,
70 {
71 self.editor = Some(editor.into());
72 }
73
74 pub fn pager(&self) -> String {
75 if let Some(pager) = &self.pager {
76 pager.to_owned()
77 } else if let Ok(pager) = std::env::var("PAGER") {
78 pager.to_string()
79 } else {
80 "less".to_string()
81 }
82 }
83
84 pub fn set_pager<T>(&mut self, pager: T)
85 where
86 T: Into<String>,
87 {
88 self.pager = Some(pager.into());
89 }
90}
91
92#[derive(Serialize, Deserialize, Default)]
93pub struct UiConfig {
94 colors: Option<bool>,
95}
96
97impl UiConfig {
98 pub fn colors(&self) -> bool {
99 if std::env::var("NO_COLOR").is_ok() {
100 false
101 } else if let Ok(clicolor) = std::env::var("CLICOLOR_FORCE") {
102 clicolor == "0"
103 } else if let Ok(clicolor) = std::env::var("CLICOLOR") {
104 clicolor == "0"
105 } else if let Some(colors) = self.colors {
106 colors
107 } else {
108 true
109 }
110 }
111
112 pub fn set_colors(&mut self, colors: bool) {
113 self.colors = Some(colors);
114 }
115}