Skip to main content

spotify_launcher/
config.rs

1use 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}