spotify_launcher/
config.rs1use crate::errors::*;
2use serde::{Deserialize, Serialize};
3use std::fs;
4use std::path::{Path, PathBuf};
5
6#[derive(Debug, Default, PartialEq, Serialize, Deserialize)]
7pub struct ConfigFile {
8 #[serde(default)]
9 pub spotify: SpotifyConfig,
10}
11
12impl ConfigFile {
13 pub fn parse(s: &str) -> Result<ConfigFile> {
14 let c = toml::from_str(s)?;
15 Ok(c)
16 }
17
18 pub fn load_from(path: &Path) -> Result<ConfigFile> {
19 info!("Loading configuration file at {:?}", path);
20 let buf = fs::read_to_string(path)
21 .with_context(|| anyhow!("Failed to read config file at {:?}", path))?;
22 Self::parse(&buf)
23 }
24
25 pub fn locate_file() -> Result<Option<PathBuf>> {
26 for path in [dirs::config_dir(), Some(PathBuf::from("/etc/"))]
27 .into_iter()
28 .flatten()
29 {
30 let path = path.join("spotify-launcher.conf");
31 debug!("Searching for configuration file at {:?}", path);
32 if path.exists() {
33 debug!("Found configuration file at {:?}", path);
34 return Ok(Some(path));
35 }
36 }
37 Ok(None)
38 }
39
40 pub fn load() -> Result<ConfigFile> {
41 if let Some(path) = Self::locate_file()? {
42 Self::load_from(&path)
43 } else {
44 info!("No configuration file found, using default config");
45 Ok(Self::default())
46 }
47 }
48}
49
50#[derive(Debug, Default, PartialEq, Serialize, Deserialize)]
51pub struct SpotifyConfig {
52 #[serde(default)]
53 pub extra_arguments: Vec<String>,
54 #[serde(default)]
55 pub extra_env_vars: Vec<String>,
56 pub download_attempts: Option<usize>,
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn test_empty_config() -> Result<()> {
65 let cf = ConfigFile::parse("")?;
66 assert_eq!(cf, ConfigFile::default());
67 Ok(())
68 }
69
70 #[test]
71 fn test_empty_spotify_config() -> Result<()> {
72 let cf = ConfigFile::parse("[spotify]")?;
73 assert_eq!(cf, ConfigFile::default());
74 Ok(())
75 }
76}