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 {
65        /// The directory that cannot be created.
66        dir: String,
67        /// The source error.
68        source: std::io::Error,
69    },
70}
71
72/// Returns the first Signstar configuration file available, or [`None`] if none found.
73///
74/// Considers files named `config.toml` in the following directories in descending priority:
75/// - `/etc/signstar`
76/// - `/run/signstar`
77/// - `/usr/local/share/signstar`
78/// - `/usr/share/signstar`
79///
80/// The first existing file is returned.
81/// If no file is found [`None`] is returned.
82pub fn get_config_file() -> Option<PathBuf> {
83    [
84        get_etc_override_config_file_path(),
85        get_run_override_config_file_path(),
86        get_usr_local_override_config_file_path(),
87        get_default_config_file_path(),
88    ]
89    .into_iter()
90    .find(|file| file.is_file())
91}
92
93/// Returns the first Signstar configuration file available, or the default if none found.
94///
95/// Considers files named `config.toml` in the following directories in descending priority:
96/// - `/etc/signstar`
97/// - `/run/signstar`
98/// - `/usr/local/share/signstar`
99/// - `/usr/share/signstar`
100///
101/// The first existing file is returned.
102/// If no file is found, the default location `/usr/share/signstar/config.toml` is returned.
103pub fn get_config_file_or_default() -> PathBuf {
104    let Some(config) = get_config_file() else {
105        return get_default_config_file_path();
106    };
107    config
108}
109
110/// Returns a list of all configuration file locations, sorted by precedence.
111pub fn get_config_file_paths() -> Vec<PathBuf> {
112    vec![
113        get_etc_override_config_file_path(),
114        get_run_override_config_file_path(),
115        get_usr_local_override_config_file_path(),
116        get_default_config_file_path(),
117    ]
118}
119
120/// Returns the file path of the configuration file override below /etc.
121pub fn get_etc_override_config_file_path() -> PathBuf {
122    PathBuf::from([ETC_OVERRIDE_CONFIG_DIR, CONFIG_FILE].concat())
123}
124
125/// Returns the directory path of the configuration override directory below /etc.
126pub fn get_etc_override_dir_path() -> PathBuf {
127    PathBuf::from(ETC_OVERRIDE_CONFIG_DIR)
128}
129
130/// Returns the file path of the configuration file override below /run.
131pub fn get_run_override_config_file_path() -> PathBuf {
132    PathBuf::from([RUN_OVERRIDE_CONFIG_DIR, CONFIG_FILE].concat())
133}
134
135/// Returns the directory path of the configuration override directory below /run.
136pub fn get_run_override_dir_path() -> PathBuf {
137    PathBuf::from(RUN_OVERRIDE_CONFIG_DIR)
138}
139
140/// Returns the file path of the configuration file override below /usr/local.
141pub fn get_usr_local_override_config_file_path() -> PathBuf {
142    PathBuf::from([USR_LOCAL_OVERRIDE_CONFIG_DIR, CONFIG_FILE].concat())
143}
144
145/// Returns the directory path of the configuration override directory below /usr/local.
146pub fn get_usr_local_override_dir_path() -> PathBuf {
147    PathBuf::from(USR_LOCAL_OVERRIDE_CONFIG_DIR)
148}
149
150/// Returns the file path of the default configuration file /usr.
151pub fn get_default_config_file_path() -> PathBuf {
152    PathBuf::from([DEFAULT_CONFIG_DIR, CONFIG_FILE].concat())
153}
154
155/// Returns the directory path of the default configuration directory below /usr.
156pub fn get_default_config_dir_path() -> PathBuf {
157    PathBuf::from(DEFAULT_CONFIG_DIR)
158}
159
160/// Creates the default configuration directory below /usr.
161///
162/// # Errors
163///
164/// Returns an error if the directory or one of its parents can not be created.
165/// Refer to [`create_dir_all`] for further information on failure scenarios.
166pub fn create_default_config_dir() -> Result<(), Error> {
167    create_dir_all(get_default_config_dir_path()).map_err(|source| Error::CreateDirectory {
168        dir: DEFAULT_CONFIG_DIR.to_string(),
169        source,
170    })
171}
172
173/// Creates the configuration override dir below /etc.
174///
175/// # Errors
176///
177/// Returns an error if the directory or one of its parents can not be created.
178/// Refer to [`create_dir_all`] for further information on failure scenarios.
179pub fn create_etc_override_config_dir() -> Result<(), Error> {
180    create_dir_all(get_etc_override_dir_path()).map_err(|source| Error::CreateDirectory {
181        dir: ETC_OVERRIDE_CONFIG_DIR.to_string(),
182        source,
183    })
184}
185
186/// Creates the configuration override dir below /run.
187///
188/// # Errors
189///
190/// Returns an error if the directory or one of its parents can not be created.
191/// Refer to [`create_dir_all`] for further information on failure scenarios.
192pub fn create_run_override_config_dir() -> Result<(), Error> {
193    create_dir_all(get_run_override_dir_path()).map_err(|source| Error::CreateDirectory {
194        dir: RUN_OVERRIDE_CONFIG_DIR.to_string(),
195        source,
196    })
197}
198
199/// Creates the configuration override dir below /usr/local.
200///
201/// # Errors
202///
203/// Returns an error if the directory or one of its parents can not be created.
204/// Refer to [`create_dir_all`] for further information on failure scenarios.
205pub fn create_usr_local_override_config_dir() -> Result<(), Error> {
206    create_dir_all(get_usr_local_override_dir_path()).map_err(|source| Error::CreateDirectory {
207        dir: USR_LOCAL_OVERRIDE_CONFIG_DIR.to_string(),
208        source,
209    })
210}