]>
Commit | Line | Data |
---|---|---|
4064639d | 1 | use serde::{Deserialize, Serialize}; |
39ff8a11 | 2 | use serde_json::{from_str, to_string}; |
44e7b4de RBR |
3 | use std::env; |
4 | use std::fs::{create_dir_all, write, File}; | |
5 | use std::io::{Read, Result}; | |
6 | use std::path::PathBuf; | |
44e7b4de RBR |
7 | |
8 | const CONFIG_ENV_VARIABLE: &str = "LYRICLI_CONFIG_DIRECTORY"; | |
9 | const CONFIG_DEFAULT_LOCATION: &str = "XDG_CONFIG_HOME"; | |
10 | const CONFIG_FALLBACK_LOCATION: &str = ".config"; | |
040b91a7 | 11 | const CONFIG_SUBDIRECTORY: &str = "lyricli"; |
44e7b4de RBR |
12 | const CONFIG_FILENAME: &str = "lyricli.conf"; |
13 | ||
14 | #[derive(Serialize, Deserialize, Debug)] | |
15 | pub struct Configuration { | |
4064639d | 16 | enabled_sources: Vec<String>, |
44e7b4de RBR |
17 | } |
18 | ||
19 | impl Configuration { | |
4064639d | 20 | pub fn new() -> Self { |
44e7b4de RBR |
21 | if let Some(configuration) = Configuration::read() { |
22 | return configuration; | |
23 | } | |
24 | ||
25 | let configuration = Configuration::default(); | |
26 | ||
27 | // Write the defaults. | |
28 | Configuration::write(&configuration).ok(); | |
29 | configuration | |
30 | } | |
31 | ||
32 | // Public API | |
33 | ||
34 | pub fn is_enabled(&self, source_name: &String) -> bool { | |
35 | self.enabled_sources.contains(source_name) | |
36 | } | |
37 | ||
38 | pub fn enable_source(&mut self, source_name: &String) -> Result<()> { | |
39 | if !self.enabled_sources.contains(source_name) { | |
40 | self.enabled_sources.push(source_name.to_owned()) | |
41 | } | |
42 | Configuration::write(self) | |
43 | } | |
44 | ||
45 | pub fn disable_source(&mut self, source_name: &String) -> Result<()> { | |
46 | self.enabled_sources.retain(|source| source != source_name); | |
47 | Configuration::write(self) | |
48 | } | |
49 | ||
50 | // Helpers | |
51 | ||
52 | fn default() -> Configuration { | |
53 | Configuration { | |
54 | enabled_sources: vec![ | |
55 | "apple_music".to_string(), | |
040b91a7 | 56 | "spotify".to_string(), |
4064639d RBR |
57 | "strawberry".to_string(), |
58 | ], | |
44e7b4de RBR |
59 | } |
60 | } | |
61 | ||
62 | fn read() -> Option<Configuration> { | |
63 | let config_file_path = Configuration::file_path(); | |
64 | ||
65 | let mut config_file = File::open(&config_file_path).ok()?; | |
66 | let mut config_contents = String::new(); | |
67 | config_file.read_to_string(&mut config_contents).ok()?; | |
39ff8a11 | 68 | from_str(&config_contents).ok()? |
44e7b4de RBR |
69 | } |
70 | ||
71 | fn write(configuration: &Configuration) -> Result<()> { | |
72 | let config_file_path = Configuration::file_path(); | |
39ff8a11 | 73 | if let Ok(serialized_configuration) = to_string(&configuration) { |
44e7b4de RBR |
74 | write(&config_file_path, serialized_configuration)?; |
75 | } | |
76 | Ok(()) | |
77 | } | |
78 | ||
79 | fn file_path() -> PathBuf { | |
80 | let config_directory = Configuration::directory(); | |
81 | create_dir_all(&config_directory).ok(); | |
82 | config_directory.join(CONFIG_FILENAME) | |
83 | } | |
84 | ||
85 | fn directory() -> PathBuf { | |
86 | match env::var(CONFIG_ENV_VARIABLE) { | |
87 | Ok(directory) => PathBuf::from(directory), | |
88 | Err(_) => match env::var(CONFIG_DEFAULT_LOCATION) { | |
89 | Ok(directory) => PathBuf::from(directory), | |
90 | Err(_) => match env::var("HOME") { | |
91 | Ok(directory) => PathBuf::from(directory).join(CONFIG_FALLBACK_LOCATION), | |
4064639d RBR |
92 | Err(_) => panic!( |
93 | "Could not find required directory, {} or {} should be set and readable.", | |
94 | CONFIG_ENV_VARIABLE, CONFIG_DEFAULT_LOCATION | |
95 | ), | |
44e7b4de RBR |
96 | }, |
97 | }, | |
4064639d RBR |
98 | } |
99 | .join(CONFIG_SUBDIRECTORY) | |
44e7b4de RBR |
100 | } |
101 | } |