Skip to main content

idemio/config/
mod.rs

1use serde::Serialize;
2use serde::de::DeserializeOwned;
3use std::fs::File;
4use std::path::Path;
5use thiserror::Error;
6
7#[derive(Debug)]
8pub struct HandlerConfig<C>
9where
10    C: Default + DeserializeOwned,
11{
12    id: String,
13    enabled: bool,
14    timeout: Option<u64>,
15    retry_count: Option<u32>,
16    retry_delay: Option<u64>,
17    config: Config<C>,
18}
19
20impl<C> Default for HandlerConfig<C>
21where
22    C: Default + DeserializeOwned,
23{
24    fn default() -> Self {
25        Self {
26            id: "unknown".to_string(),
27            enabled: true,
28            timeout: Some(30000),
29            retry_count: None,
30            retry_delay: None,
31            config: Config::default(),
32        }
33    }
34}
35
36impl<C> HandlerConfig<C>
37where
38    C: Default + DeserializeOwned,
39{
40    pub fn new(id: String, config: Config<C>) -> Self {
41        Self {
42            id,
43            config,
44            ..Default::default()
45        }
46    }
47
48    pub fn id(&self) -> &String {
49        &self.id
50    }
51
52    pub fn enabled(&self) -> bool {
53        self.enabled
54    }
55
56    pub fn timeout(&self) -> Option<u64> {
57        self.timeout
58    }
59
60    pub fn retry_count(&self) -> Option<u32> {
61        self.retry_count
62    }
63
64    pub fn retry_delay(&self) -> Option<u64> {
65        self.retry_delay
66    }
67
68    pub fn config(&self) -> &Config<C> {
69        &self.config
70    }
71
72    pub fn set_config(&mut self, config: Config<C>) {
73        self.config = config;
74    }
75
76    pub fn set_enabled(&mut self, enabled: bool) {
77        self.enabled = enabled;
78    }
79
80    pub fn set_timeout(&mut self, timeout: Option<u64>) {
81        self.timeout = timeout;
82    }
83
84    pub fn set_retry_count(&mut self, retry_count: Option<u32>) {
85        self.retry_count = retry_count;
86    }
87
88    pub fn set_retry_delay(&mut self, retry_delay: Option<u64>) {
89        self.retry_delay = retry_delay;
90    }
91
92    pub fn set_id(&mut self, id: String) {
93        self.id = id;
94    }
95
96    pub fn builder() -> HandlerConfigBuilder<C> {
97        HandlerConfigBuilder::new()
98    }
99}
100
101pub struct HandlerConfigBuilder<C>
102where
103    C: Default + DeserializeOwned,
104{
105    config: HandlerConfig<C>,
106}
107
108impl<C> HandlerConfigBuilder<C>
109where
110    C: Default + DeserializeOwned,
111{
112    pub fn new() -> Self {
113        Self {
114            config: HandlerConfig::<C>::default(),
115        }
116    }
117
118    pub fn id(&mut self, id: impl Into<String>) -> &mut Self {
119        self.config.id = id.into();
120        self
121    }
122
123    pub fn enabled(&mut self, enabled: bool) -> &mut Self {
124        self.config.enabled = enabled;
125        self
126    }
127
128    pub fn timeout(&mut self, timeout: Option<u64>) -> &mut Self {
129        self.config.timeout = timeout;
130        self
131    }
132
133    pub fn retry_count(&mut self, retry_count: Option<u32>) -> &mut Self {
134        self.config.retry_count = retry_count;
135        self
136    }
137
138    pub fn retry_delay(&mut self, retry_delay: Option<u64>) -> &mut Self {
139        self.config.retry_delay = retry_delay;
140        self
141    }
142
143    pub fn handler_config(&mut self, config: Config<C>) -> &mut Self {
144        self.config.config = config;
145        self
146    }
147
148    pub fn build(self) -> HandlerConfig<C> {
149        self.config
150    }
151}
152
153#[derive(Debug, Default)]
154pub struct Config<C> {
155    config: C,
156}
157
158impl<C> Config<C>
159where
160    C: Default + DeserializeOwned,
161{
162    pub fn new(provider: impl ConfigProvider<C>) -> Result<Self, ()> {
163        provider
164            .load()
165            .map(|config| Config { config })
166            .map_err(|_| ())
167    }
168
169    pub fn get(&self) -> &C {
170        &self.config
171    }
172
173    pub fn get_mut(&mut self) -> &mut C {
174        &mut self.config
175    }
176}
177
178pub trait ConfigProvider<C>
179where
180    C: Default + DeserializeOwned,
181{
182    fn load(&self) -> Result<C, ConfigProviderError>;
183}
184
185pub struct DefaultConfigProvider;
186
187impl<C> ConfigProvider<C> for DefaultConfigProvider
188where
189    C: Default + DeserializeOwned,
190{
191    fn load(&self) -> Result<C, ConfigProviderError> {
192        Ok(C::default())
193    }
194}
195
196pub struct FileConfigProvider {
197    pub base_path: String,
198    pub config_name: String,
199}
200
201impl<C> ConfigProvider<C> for FileConfigProvider
202where
203    C: Default + DeserializeOwned,
204{
205    fn load(&self) -> Result<C, ConfigProviderError> {
206        let config_path = Path::new(&self.base_path).join(&self.config_name);
207        let file = File::open(config_path).map_err(|e| {
208            let msg = format!("Could not open config file: {}", e);
209            ConfigProviderError::load_error(msg)
210        })?;
211        serde_json::from_reader(file).map_err(|e| {
212            let msg = format!("Could not load config file from reader: {}", e);
213            ConfigProviderError::load_error(msg)
214        })
215    }
216}
217
218pub struct ProgrammaticConfigProvider<C> {
219    pub config: C,
220}
221
222impl<C> ConfigProvider<C> for ProgrammaticConfigProvider<C>
223where
224    C: Default + DeserializeOwned + Clone + Serialize,
225{
226    fn load(&self) -> Result<C, ConfigProviderError> {
227        Ok(self.config.clone())
228    }
229}
230
231pub enum ProviderType {
232    File,
233    Default,
234}
235
236#[derive(Error, Debug)]
237pub enum ConfigProviderError {
238    #[error("Could not load config file. {message}")]
239    Load { message: String },
240}
241
242impl ConfigProviderError {
243    #[inline]
244    pub(crate) fn load_error(msg: impl Into<String>) -> Self {
245        Self::Load {
246            message: msg.into(),
247        }
248    }
249}