autopulse_service/settings/
mod.rs1use app::App;
2use auth::Auth;
3use config::Config;
4use opts::Opts;
5use serde::{Deserialize, Serialize};
6use std::env;
7use std::{collections::HashMap, path::PathBuf};
8use targets::Target;
9use triggers::manual::Manual;
10use triggers::Trigger;
11use webhooks::Webhook;
12
13pub mod app;
25
26pub mod auth;
36
37pub mod opts;
49
50pub use autopulse_utils::rewrite;
62
63pub mod timer;
75
76pub mod triggers;
80
81pub mod targets;
85
86pub mod webhooks;
90
91#[doc(hidden)]
92pub fn default_triggers() -> HashMap<String, Trigger> {
93 let mut triggers = HashMap::new();
94
95 triggers.insert(
96 "manual".to_string(),
97 Trigger::Manual(Manual {
98 rewrite: None,
99 timer: None,
100 excludes: vec![],
101 }),
102 );
103
104 triggers
105}
106
107#[derive(Serialize, Deserialize, Clone)]
108pub struct Settings {
109 #[serde(default)]
110 pub app: App,
111
112 #[serde(default)]
113 pub auth: Auth,
114
115 #[serde(default)]
116 pub opts: Opts,
117
118 #[serde(default = "default_triggers")]
119 pub triggers: HashMap<String, Trigger>,
120 #[serde(default)]
121 pub targets: HashMap<String, Target>,
122
123 #[serde(default)]
124 pub webhooks: HashMap<String, Webhook>,
125
126 #[serde(default)]
138 pub anchors: Vec<PathBuf>,
139}
140
141impl Default for Settings {
142 fn default() -> Self {
143 Self {
144 app: App::default(),
145 auth: Auth::default(),
146 opts: Opts::default(),
147 triggers: default_triggers(),
148 targets: HashMap::new(),
149 webhooks: HashMap::new(),
150 anchors: vec![],
151 }
152 }
153}
154
155impl Settings {
156 fn resolve_env() -> HashMap<String, String> {
157 let mut out = HashMap::new();
158
159 for (key, value) in env::vars() {
160 if let Some(base) = key.strip_suffix("__FILE") {
161 if let Ok(file_value) = std::fs::read_to_string(&value) {
162 out.insert(base.to_string(), file_value.trim().to_string());
163 continue;
164 }
165 }
166
167 out.entry(key).or_insert(value);
168 }
169
170 out
171 }
172
173 pub fn get_settings(optional_config_file: Option<String>) -> anyhow::Result<Self> {
174 let mut settings = Config::builder()
175 .add_source(config::File::with_name("config").required(false))
176 .add_source(
177 config::Environment::with_prefix("AUTOPULSE")
178 .separator("__")
179 .source(Some(Self::resolve_env())),
180 );
181
182 if let Some(file_loc) = optional_config_file {
183 settings = settings.add_source(config::File::with_name(&file_loc));
184 }
185
186 let settings = settings.build()?;
187
188 let mut settings = settings
189 .try_deserialize::<Self>()
190 .map_err(|e| anyhow::anyhow!(e))?;
191
192 settings.add_default_manual_trigger()?;
193
194 Ok(settings)
195 }
196
197 pub fn add_default_manual_trigger(&mut self) -> anyhow::Result<()> {
198 if !self.triggers.contains_key("manual") {
199 self.triggers.insert(
200 "manual".to_string(),
201 Trigger::Manual(Manual {
202 rewrite: None,
203 timer: None,
204 excludes: vec![],
205 }),
206 );
207 }
208
209 Ok(())
210 }
211}