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}