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