workmn 0.0.5

Manages the lifecycle of projects on the local machine
Documentation
use crate::util::glob_err;
use directories::ProjectDirs;
use log::warn;
use std::path::PathBuf;

pub trait ConfLocation {
    fn project_files(&self) -> Vec<PathBuf>;
    fn tag_files(&self) -> Vec<PathBuf>;
}

pub struct ConfFolderLocation {
    pub dir: PathBuf,
}

impl ConfFolderLocation {
    pub fn new(dir: PathBuf) -> Self {
        Self { dir }
    }
}

impl Default for ConfFolderLocation {
    fn default() -> Self {
        let dirs = ProjectDirs::from(
            crate::APP_NAME_QUALIFIER,
            crate::APP_NAME_ORGANIZATION,
            crate::APP_NAME,
        )
        .expect("Unable to determine config location");

        Self::new(dirs.config_dir().to_owned())
    }
}

fn get_toml_paths(file: PathBuf, folder: PathBuf, err_type: &'static str) -> Vec<PathBuf> {
    let mut paths = Vec::new();

    if let Ok(metadata) = file.metadata() {
        if metadata.is_file() {
            paths.push(file);
        }
    }

    let glob_error = |err: globwalk::WalkError| {
        warn!(
            "unable to load {} from path {:?}: {}",
            err_type,
            err.path(),
            err
        );
    };

    if let Ok(metadata) = folder.metadata() {
        if metadata.is_dir() {
            for path in glob_err(folder, "**/*.toml", glob_error) {
                paths.push(path);
            }
        }
    }

    paths
}

impl ConfLocation for ConfFolderLocation {
    fn project_files(&self) -> Vec<PathBuf> {
        get_toml_paths(
            self.dir.join("projects.toml"),
            self.dir.join("projects.d"),
            "projects",
        )
    }

    fn tag_files(&self) -> Vec<PathBuf> {
        get_toml_paths(self.dir.join("tags.toml"), self.dir.join("tags.d"), "tags")
    }
}