@@ -10,7 +10,7 @@ use ser::ConfigSerializer;
10
10
use source:: Source ;
11
11
12
12
use path;
13
- use value:: { Value , ValueKind , ValueWithKey } ;
13
+ use value:: { Table , Value , ValueKind , ValueWithKey } ;
14
14
15
15
#[ derive( Clone , Debug ) ]
16
16
enum ConfigKind {
@@ -49,7 +49,12 @@ pub struct Config {
49
49
50
50
impl Config {
51
51
pub fn new ( ) -> Self {
52
- Config :: default ( )
52
+ Self {
53
+ kind : ConfigKind :: default ( ) ,
54
+ // Config root should be instantiated as an empty table
55
+ // to avoid deserialization errors.
56
+ cache : Value :: new ( None , Table :: new ( ) ) ,
57
+ }
53
58
}
54
59
55
60
/// Merge in a configuration property source.
@@ -129,6 +134,26 @@ impl Config {
129
134
self . refresh ( )
130
135
}
131
136
137
+ /// Set the configuration defaults by serializing them from given value.
138
+ pub fn set_defaults < T > ( & mut self , value : & T ) -> Result < & mut Config >
139
+ where
140
+ T : Serialize ,
141
+ {
142
+ match self . kind {
143
+ ConfigKind :: Mutable {
144
+ ref mut defaults, ..
145
+ } => {
146
+ for ( key, val) in Self :: try_from ( & value) ?. collect ( ) ? {
147
+ defaults. insert ( key. parse ( ) ?, val) ;
148
+ }
149
+ }
150
+
151
+ ConfigKind :: Frozen => return Err ( ConfigError :: Frozen ) ,
152
+ }
153
+
154
+ self . refresh ( )
155
+ }
156
+
132
157
pub fn set < T > ( & mut self , key : & str , value : T ) -> Result < & mut Config >
133
158
where
134
159
T : Into < Value > ,
@@ -192,13 +217,21 @@ impl Config {
192
217
T :: deserialize ( self )
193
218
}
194
219
195
- /// Attempt to deserialize the entire configuration into the requested type.
220
+ /// Attempt to serialize the entire configuration from the given type.
196
221
pub fn try_from < T : Serialize > ( from : & T ) -> Result < Self > {
197
222
let mut serializer = ConfigSerializer :: default ( ) ;
198
223
from. serialize ( & mut serializer) ?;
199
224
Ok ( serializer. output )
200
225
}
201
226
227
+ /// Attempt to serialize the entire configuration from the given type
228
+ /// as default values.
229
+ pub fn try_defaults_from < T : Serialize > ( from : & T ) -> Result < Self > {
230
+ let mut c = Self :: new ( ) ;
231
+ c. set_defaults ( from) ?;
232
+ Ok ( c)
233
+ }
234
+
202
235
#[ deprecated( since = "0.7.0" , note = "please use 'try_into' instead" ) ]
203
236
pub fn deserialize < ' de , T : Deserialize < ' de > > ( self ) -> Result < T > {
204
237
self . try_into ( )
0 commit comments