1#![expect(
4 clippy::derive_partial_eq_without_eq,
5 reason = "Non-`Eq` typed attributes may be added \
6 to the configuration in the future."
7)]
8
9#[cfg(feature = "serde")]
10use figment::{
11 providers::{Format, Serialized, Toml},
12 Figment,
13};
14
15#[cfg(feature = "serde")]
16use serde::{Deserialize, Serialize};
17use std::path::PathBuf;
18
19#[cfg(feature = "serde")]
20use crate::path::git_root;
21
22#[cfg_attr(
26 feature = "serde",
27 doc = "[`read()`](Self::read) and [`figment()`](Self::figment) can be used to obtain configuration from files."
28)]
29#[derive(Debug, Default, Clone, PartialEq)]
30#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
31#[cfg_attr(feature = "serde", serde(default))]
32pub struct Config {
33 pub paths: Paths,
35}
36
37#[derive(Debug, Default, Clone, PartialEq)]
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
40#[cfg_attr(feature = "serde", serde(default))]
41pub struct Paths {
42 pub scripts: ScriptPaths,
44}
45
46#[derive(Debug, Clone, PartialEq)]
48#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
49#[cfg_attr(feature = "serde", serde(default))]
50pub struct ScriptPaths {
51 pub system: Vec<PathBuf>,
55
56 pub user: Vec<PathBuf>,
60
61 pub repository: Vec<PathBuf>,
69}
70
71impl Config {
72 #[cfg(feature = "serde")]
79 pub fn figment() -> Figment {
80 let user_home = home::home_dir().unwrap_or_default();
81 let git_root = git_root().unwrap_or_default();
82
83 let mut figment = Figment::new()
84 .merge(Serialized::defaults(Self::default()))
85 .merge(Toml::file("/etc/devscripts/config.toml"))
86 .merge(Toml::file(
87 user_home.join("./.config/devscripts/config.toml"),
88 ));
89
90 if let Some(git_root) = git_root {
91 figment = figment.merge(Toml::file(git_root.join("./.devscripts/.config.toml")));
92 }
93
94 figment
95 }
96
97 #[cfg(feature = "serde")]
102 pub fn read() -> Result<Self, figment::Error> {
103 Self::figment().extract()
104 }
105}
106
107impl Default for ScriptPaths {
108 fn default() -> Self {
109 Self {
110 system: vec![
111 "/usr/share/devscripts".into(),
112 "/usr/local/share/devscripts".into(),
113 ],
114 user: vec!["~/.local/share/devscripts".into()],
115 repository: vec!["./.devscripts".into()],
116 }
117 }
118}