1use std::fmt::Debug;
2
3use crate::builder::{ConfigBuilder, DefaultState};
4use serde::de::Deserialize;
5use serde::ser::Serialize;
6
7use crate::error::{ConfigError, Result};
8use crate::map::Map;
9use crate::path;
10use crate::ser::ConfigSerializer;
11use crate::source::Source;
12use crate::value::{Table, Value};
13
14#[derive(Clone, Debug)]
18pub struct Config {
19 defaults: Map<path::Expression, Value>,
20 overrides: Map<path::Expression, Value>,
21 sources: Vec<Box<dyn Source + Send + Sync>>,
22
23 pub cache: Value,
25}
26
27impl Default for Config {
28 fn default() -> Self {
29 Self {
30 defaults: Default::default(),
31 overrides: Default::default(),
32 sources: Default::default(),
33 cache: Value::new(None, Table::new()),
34 }
35 }
36}
37
38impl Config {
39 pub(crate) fn new(value: Value) -> Self {
40 Self {
41 cache: value,
42 ..Self::default()
43 }
44 }
45
46 pub fn builder() -> ConfigBuilder<DefaultState> {
48 ConfigBuilder::<DefaultState>::default()
49 }
50
51 #[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
53 pub fn merge<T>(&mut self, source: T) -> Result<&mut Self>
54 where
55 T: 'static,
56 T: Source + Send + Sync,
57 {
58 self.sources.push(Box::new(source));
59
60 #[allow(deprecated)]
61 self.refresh()
62 }
63
64 #[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
66 pub fn with_merged<T>(mut self, source: T) -> Result<Self>
67 where
68 T: 'static,
69 T: Source + Send + Sync,
70 {
71 self.sources.push(Box::new(source));
72
73 #[allow(deprecated)]
74 self.refresh()?;
75 Ok(self)
76 }
77
78 #[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
84 pub fn refresh(&mut self) -> Result<&mut Self> {
85 self.cache = {
86 let mut cache: Value = Map::<String, Value>::new().into();
87
88 for (key, val) in &self.defaults {
90 key.set(&mut cache, val.clone());
91 }
92
93 self.sources.collect_to(&mut cache)?;
95
96 for (key, val) in &self.overrides {
98 key.set(&mut cache, val.clone());
99 }
100
101 cache
102 };
103
104 Ok(self)
105 }
106
107 #[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
109 pub fn set_default<T>(&mut self, key: &str, value: T) -> Result<&mut Self>
110 where
111 T: Into<Value>,
112 {
113 self.defaults
114 .insert(key.to_lowercase().as_str().parse()?, value.into());
115
116 #[allow(deprecated)]
117 self.refresh()
118 }
119
120 #[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
129 pub fn set<T>(&mut self, key: &str, value: T) -> Result<&mut Self>
130 where
131 T: Into<Value>,
132 {
133 self.overrides
134 .insert(key.to_lowercase().as_str().parse()?, value.into());
135
136 #[allow(deprecated)]
137 self.refresh()
138 }
139
140 #[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
141 pub fn set_once(&mut self, key: &str, value: Value) -> Result<()> {
142 let expr: path::Expression = key.to_lowercase().as_str().parse()?;
143
144 if let Some(ref mut val) = expr.get_mut(&mut self.cache) {
146 **val = value;
147 } else {
148 expr.set(&mut self.cache, value);
149 }
150 Ok(())
151 }
152
153 fn get_value(&self, key: &str) -> Result<Value> {
154 let k = key.to_lowercase();
155 let key = k.as_str();
156 let expr: path::Expression = key.parse()?;
158
159 let value = expr.get(&self.cache).cloned();
161
162 value.ok_or_else(|| ConfigError::NotFound(key.into()))
163 }
164
165 pub fn get<'de, T: Deserialize<'de>>(&self, key: &str) -> Result<T> {
166 self.get_value(key).and_then(|value| {
167 T::deserialize(value).map_err(|e| e.extend_with_key(key))
169 })
170 }
171
172 pub fn get_string(&self, key: &str) -> Result<String> {
173 self.get_value(key)
174 .and_then(|value| value.into_string().map_err(|e| e.extend_with_key(key)))
175 }
176
177 pub fn get_int(&self, key: &str) -> Result<i64> {
178 self.get_value(key)
179 .and_then(|value| value.into_int().map_err(|e| e.extend_with_key(key)))
180 }
181
182 pub fn get_float(&self, key: &str) -> Result<f64> {
183 self.get_value(key)
184 .and_then(|value| value.into_float().map_err(|e| e.extend_with_key(key)))
185 }
186
187 pub fn get_bool(&self, key: &str) -> Result<bool> {
188 self.get_value(key)
189 .and_then(|value| value.into_bool().map_err(|e| e.extend_with_key(key)))
190 }
191
192 pub fn get_table(&self, key: &str) -> Result<Map<String, Value>> {
193 self.get_value(key)
194 .and_then(|value| value.into_table().map_err(|e| e.extend_with_key(key)))
195 }
196
197 pub fn get_array(&self, key: &str) -> Result<Vec<Value>> {
198 self.get_value(key)
199 .and_then(|value| value.into_array().map_err(|e| e.extend_with_key(key)))
200 }
201
202 pub fn try_deserialize<'de, T: Deserialize<'de>>(self) -> Result<T> {
204 T::deserialize(self)
205 }
206
207 pub fn try_from<T: Serialize>(from: &T) -> Result<Self> {
209 let mut serializer = ConfigSerializer::default();
210 from.serialize(&mut serializer)?;
211 Ok(serializer.output)
212 }
213
214 #[deprecated(since = "0.7.0", note = "please use 'try_deserialize' instead")]
215 pub fn deserialize<'de, T: Deserialize<'de>>(self) -> Result<T> {
216 self.try_deserialize()
217 }
218}
219
220impl Source for Config {
221 fn clone_into_box(&self) -> Box<dyn Source + Send + Sync> {
222 Box::new((*self).clone())
223 }
224
225 fn collect(&self) -> Result<Map<String, Value>> {
226 self.cache.clone().into_table()
227 }
228}