xdg-termfilechooser-bridge 0.2.6

The bridge between xdg-desktop-portal-termfilechooser and your favorite terminal based filepicker
use std::{
    fs,
    io::{Error, ErrorKind},
};

use serde::{Deserialize, Serialize};

use crate::{
    constants::APP_NAME,
    filepicker::{FilePicker, filepicker_from_env},
    terminals::{Terminal, terminal_from_env},
};

#[derive(Serialize, Deserialize, Clone, Default)]
pub struct Config {
    pub terminal: Option<Terminal>,
    pub filepicker: Option<FilePicker>,
    pub start_at_last_selected_dir: Option<bool>,
}

impl Config {
    pub fn from_env() -> std::io::Result<Config> {
        Ok(Config {
            terminal: Some(terminal_from_env()),
            filepicker: Some(filepicker_from_env()),
            start_at_last_selected_dir: Some(true),
        })
    }

    pub fn load() -> std::io::Result<Config> {
        let config_dir = dirs::config_dir();

        if config_dir.is_none() {
            return Err(Error::new(
                ErrorKind::NotFound,
                "Could not determine config dir",
            ));
        }

        let config_dir = config_dir.unwrap();
        let config_dir = config_dir.join(APP_NAME);

        fs::create_dir_all(&config_dir)?;

        let config_file = config_dir.join("config.toml");

        let mut config = Config::from_env()?;

        if config_file.exists() {
            let contents = fs::read_to_string(config_file)?;

            let other_config: Config =
                toml::from_str(&contents).expect("could not parse toml file");

            config = config.merge(&other_config);
        }

        Ok(config)
    }

    fn merge(&self, other_config: &Config) -> Config {
        let mut new_config = self.clone();

        if other_config.terminal.is_some() {
            new_config.terminal = other_config.terminal.clone();
        }

        if other_config.filepicker.is_some() {
            new_config.filepicker = other_config.filepicker.clone();
        }

        if other_config.start_at_last_selected_dir.is_some() {
            new_config.start_at_last_selected_dir = other_config.start_at_last_selected_dir;
        }

        new_config
    }
}