signstar_common/
config.rs

1//! Default locations for Signstar configuration files.
2//!
3//! # Examples
4//!
5//! ```
6//! use signstar_common::config::{
7//!     get_config_file_or_default,
8//!     get_config_file_paths,
9//!     get_config_file,
10//!     get_default_config_dir_path,
11//!     get_default_config_file_path,
12//!     get_etc_override_config_file_path,
13//!     get_etc_override_dir_path,
14//!     get_run_override_config_file_path,
15//!     get_run_override_dir_path,
16//!     get_usr_local_override_config_file_path,
17//!     get_usr_local_override_dir_path,
18//! };
19//!
20//! // Get directory paths for Signstar configuration files.
21//! println!("{:?}", get_etc_override_dir_path());
22//! println!("{:?}", get_run_override_dir_path());
23//! println!("{:?}", get_usr_local_override_dir_path());
24//! println!("{:?}", get_default_config_dir_path());
25//!
26//! // Get file paths for Signstar configuration files.
27//! println!("{:?}", get_etc_override_config_file_path());
28//! println!("{:?}", get_run_override_config_file_path());
29//! println!("{:?}", get_usr_local_override_config_file_path());
30//! println!("{:?}", get_default_config_file_path());
31//!
32//! // Get the first config file found, according to directory precedence.
33//! println!("{:?}", get_config_file());
34//!
35//! // Get the first config file found, according to directory precedence, or the default if none are found.
36//! println!("{:?}", get_config_file_or_default());
37//!
38//! // Get all configuration file paths, sorted by directory precedence.
39//! println!("{:?}", get_config_file_paths());
40//! ```
41
42use std::{fs::create_dir_all, path::PathBuf};
43
44/// The default config directory below "/usr" for Signstar hosts.
45const DEFAULT_CONFIG_DIR: &str = "/usr/share/signstar/";
46
47/// The override config directory below "/etc" for Signstar hosts.
48const ETC_OVERRIDE_CONFIG_DIR: &str = "/etc/signstar/";
49
50/// The override config directory below "/run" for Signstar hosts.
51const RUN_OVERRIDE_CONFIG_DIR: &str = "/run/signstar/";
52
53/// The override config directory below "/usr/local" for Signstar hosts.
54const USR_LOCAL_OVERRIDE_CONFIG_DIR: &str = "/usr/local/share/signstar/";
55
56/// The filename of a Signstar configuration file.
57const CONFIG_FILE: &str = "config.toml";
58
59/// An error that may occur when handling configuration directories or files.
60#[derive(Debug, thiserror::Error)]
61pub enum Error {
62    /// A directory can not be created.
63    #[error("Unable to create directory {dir}:\n{source}")]
64    CreateDirectory { dir: String, source: std::io::Error },
65}
66
67/// Returns the first Signstar configuration file available, or [`None`] if none found.
68///
69/// Considers files named `config.toml` in the following directories in descending priority:
70/// - `/etc/signstar`
71/// - `/run/signstar`
72/// - `/usr/local/share/signstar`
73/// - `/usr/share/signstar`
74///
75/// The first existing file is returned.
76/// If no file is found [`None`] is returned.
77pub fn get_config_file() -> Option<PathBuf> {
78    [
79        get_etc_override_config_file_path(),
80        get_run_override_config_file_path(),
81        get_usr_local_override_config_file_path(),
82        get_default_config_file_path(),
83    ]
84    .into_iter()
85    .find(|file| file.is_file())
86}
87
88/// Returns the first Signstar configuration file available, or the default if none found.
89///
90/// Considers files named `config.toml` in the following directories in descending priority:
91/// - `/etc/signstar`
92/// - `/run/signstar`
93/// - `/usr/local/share/signstar`
94/// - `/usr/share/signstar`
95///
96/// The first existing file is returned.
97/// If no file is found, the default location `/usr/share/signstar/config.toml` is returned.
98pub fn get_config_file_or_default() -> PathBuf {
99    let Some(config) = get_config_file() else {
100        return get_default_config_file_path();
101    };
102    config
103}
104
105/// Returns a list of all configuration file locations, sorted by precedence.
106pub fn get_config_file_paths() -> Vec<PathBuf> {
107    vec![
108        get_etc_override_config_file_path(),
109        get_run_override_config_file_path(),
110        get_usr_local_override_config_file_path(),
111        get_default_config_file_path(),
112    ]
113}
114
115/// Returns the file path of the configuration file override below /etc.
116pub fn get_etc_override_config_file_path() -> PathBuf {
117    PathBuf::from([ETC_OVERRIDE_CONFIG_DIR, CONFIG_FILE].concat())
118}
119
120/// Returns the directory path of the configuration override directory below /etc.
121pub fn get_etc_override_dir_path() -> PathBuf {
122    PathBuf::from(ETC_OVERRIDE_CONFIG_DIR)
123}
124
125/// Returns the file path of the configuration file override below /run.
126pub fn get_run_override_config_file_path() -> PathBuf {
127    PathBuf::from([RUN_OVERRIDE_CONFIG_DIR, CONFIG_FILE].concat())
128}
129
130/// Returns the directory path of the configuration override directory below /run.
131pub fn get_run_override_dir_path() -> PathBuf {
132    PathBuf::from(RUN_OVERRIDE_CONFIG_DIR)
133}
134
135/// Returns the file path of the configuration file override below /usr/local.
136pub fn get_usr_local_override_config_file_path() -> PathBuf {
137    PathBuf::from([USR_LOCAL_OVERRIDE_CONFIG_DIR, CONFIG_FILE].concat())
138}
139
140/// Returns the directory path of the configuration override directory below /usr/local.
141pub fn get_usr_local_override_dir_path() -> PathBuf {
142    PathBuf::from(USR_LOCAL_OVERRIDE_CONFIG_DIR)
143}
144
145/// Returns the file path of the default configuration file /usr.
146pub fn get_default_config_file_path() -> PathBuf {
147    PathBuf::from([DEFAULT_CONFIG_DIR, CONFIG_FILE].concat())
148}
149
150/// Returns the directory path of the default configuration directory below /usr.
151pub fn get_default_config_dir_path() -> PathBuf {
152    PathBuf::from(DEFAULT_CONFIG_DIR)
153}
154
155/// Creates the default configuration directory below /usr.
156///
157/// # Errors
158///
159/// Returns an error if the directory or one of its parents can not be created.
160/// Refer to [`create_dir_all`] for further information on failure scenarios.
161pub fn create_default_config_dir() -> Result<(), Error> {
162    create_dir_all(get_default_config_dir_path()).map_err(|source| Error::CreateDirectory {
163        dir: DEFAULT_CONFIG_DIR.to_string(),
164        source,
165    })
166}
167
168/// Creates the configuration override dir below /etc.
169///
170/// # Errors
171///
172/// Returns an error if the directory or one of its parents can not be created.
173/// Refer to [`create_dir_all`] for further information on failure scenarios.
174pub fn create_etc_override_config_dir() -> Result<(), Error> {
175    create_dir_all(get_etc_override_dir_path()).map_err(|source| Error::CreateDirectory {
176        dir: ETC_OVERRIDE_CONFIG_DIR.to_string(),
177        source,
178    })
179}
180
181/// Creates the configuration override dir below /run.
182///
183/// # Errors
184///
185/// Returns an error if the directory or one of its parents can not be created.
186/// Refer to [`create_dir_all`] for further information on failure scenarios.
187pub fn create_run_override_config_dir() -> Result<(), Error> {
188    create_dir_all(get_run_override_dir_path()).map_err(|source| Error::CreateDirectory {
189        dir: RUN_OVERRIDE_CONFIG_DIR.to_string(),
190        source,
191    })
192}
193
194/// Creates the configuration override dir below /usr/local.
195///
196/// # Errors
197///
198/// Returns an error if the directory or one of its parents can not be created.
199/// Refer to [`create_dir_all`] for further information on failure scenarios.
200pub fn create_usr_local_override_config_dir() -> Result<(), Error> {
201    create_dir_all(get_usr_local_override_dir_path()).map_err(|source| Error::CreateDirectory {
202        dir: USR_LOCAL_OVERRIDE_CONFIG_DIR.to_string(),
203        source,
204    })
205}