libscilo/config/
paths.rs

1//! This module is dedicated to functions for finding configuration file paths.
2
3use crate::{ProjectPathError, version_control::project_root};
4use dirs::{config_dir, home_dir};
5use std::path::{Path, PathBuf};
6
7/// Find all configuration files available to be parsed.
8///
9/// Configuration files are detected in the following order:
10/// 1. `${PROJECT_ROOT}/.config/scilo/config.toml`
11/// 2. [`config_dir()`][dirs::config_dir]`/scilo/config.toml`
12///
13/// These configurations are returned in order of priority.
14/// The first element is the highest priority, so options that are defined in
15/// the first configuration file will overrule the same option in the last file.
16pub fn find_config_paths() -> Vec<PathBuf> {
17    vec![project_config_path(), user_config_path()]
18        .into_iter()
19        .filter(|dir| dir.exists())
20        .collect()
21}
22
23/// The path of the project-specific configuration
24///
25/// This evaluates to `${PROJECT_ROOT}/.config/scilo/config.toml`.
26pub fn project_config_path() -> PathBuf {
27    project_root()
28        .join(".config")
29        .join("scilo")
30        .join("config.toml")
31}
32
33/// The path of the user-specific configuration
34///
35/// This evaluates to `$XDG_CONFIG_DIR/scilo/config.toml`.
36pub fn user_config_path() -> PathBuf {
37    config_dir()
38        .unwrap_or(home_dir().unwrap().join(".config"))
39        .join("scilo")
40        .join("config.toml")
41}
42
43/// Normalize paths to be relative to the [`project_root()`][crate::project_root].
44pub fn project_path(path: &Path) -> Result<PathBuf, ProjectPathError> {
45    let abs_path = match path.canonicalize() {
46        Ok(val) => val,
47        Err(_) => return Err(ProjectPathError::CanonicalizationError(path.to_path_buf())),
48    };
49    let root_dir = project_root();
50    match abs_path.strip_prefix(root_dir) {
51        Ok(val) => Ok(val.to_path_buf()),
52        Err(_) => Err(ProjectPathError::PathNotWithinProject(path.to_path_buf()))
53    }
54}