33use crate :: lib:: error:: DfxResult ;
44use serde:: { Deserialize , Serialize } ;
55use serde_json:: { Map , Value } ;
6+ use std:: net:: { SocketAddr , ToSocketAddrs } ;
67use std:: path:: { Path , PathBuf } ;
78
89pub const CONFIG_FILE_NAME : & str = "dfinity.json" ;
@@ -15,6 +16,7 @@ const EMPTY_CONFIG_DEFAULTS_START: ConfigDefaultsStart = ConfigDefaultsStart {
1516 address : None ,
1617 port : None ,
1718 nodes : None ,
19+ serve_root : None ,
1820} ;
1921const EMPTY_CONFIG_DEFAULTS_BUILD : ConfigDefaultsBuild = ConfigDefaultsBuild { output : None } ;
2022
@@ -28,6 +30,7 @@ pub struct ConfigDefaultsStart {
2830 pub address : Option < String > ,
2931 pub nodes : Option < u64 > ,
3032 pub port : Option < u16 > ,
33+ pub serve_root : Option < String > ,
3134}
3235
3336#[ derive( Debug , Serialize , Deserialize ) ]
@@ -61,6 +64,28 @@ impl ConfigDefaultsStart {
6164 . to_owned ( )
6265 . unwrap_or_else ( || default. to_string ( ) )
6366 }
67+ pub fn get_binding_socket_addr ( & self , default : & str ) -> Option < SocketAddr > {
68+ default
69+ . to_socket_addrs ( )
70+ . ok ( )
71+ . and_then ( |mut x| x. next ( ) )
72+ . and_then ( |default_addr| {
73+ let addr = self . get_address ( default_addr. ip ( ) . to_string ( ) . as_str ( ) ) ;
74+ let port = self . get_port ( default_addr. port ( ) ) ;
75+
76+ format ! ( "{}:{}" , addr, port)
77+ . to_socket_addrs ( )
78+ . ok ( )
79+ . and_then ( |mut x| x. next ( ) )
80+ } )
81+ }
82+ pub fn get_serve_root ( & self , default : & str ) -> PathBuf {
83+ PathBuf :: from (
84+ self . serve_root
85+ . to_owned ( )
86+ . unwrap_or_else ( || default. to_string ( ) ) ,
87+ )
88+ }
6489 pub fn get_nodes ( & self , default : u64 ) -> u64 {
6590 self . nodes . unwrap_or ( default)
6691 }
@@ -136,16 +161,25 @@ impl Config {
136161 ) )
137162 }
138163
139- pub fn load_from ( working_dir : & PathBuf ) -> std:: io:: Result < Config > {
164+ pub fn from_file ( working_dir : & PathBuf ) -> std:: io:: Result < Config > {
140165 let path = Config :: resolve_config_path ( working_dir) ?;
141166 let content = std:: fs:: read ( & path) ?;
167+ Config :: from_slice ( path, & content)
168+ }
169+
170+ pub fn from_current_dir ( ) -> std:: io:: Result < Config > {
171+ Config :: from_file ( & std:: env:: current_dir ( ) ?)
172+ }
173+
174+ fn from_slice ( path : PathBuf , content : & [ u8 ] ) -> std:: io:: Result < Config > {
142175 let config = serde_json:: from_slice ( & content) ?;
143176 let json = serde_json:: from_slice ( & content) ?;
144177 Ok ( Config { path, json, config } )
145178 }
146179
147- pub fn from_current_dir ( ) -> std:: io:: Result < Config > {
148- Config :: load_from ( & std:: env:: current_dir ( ) ?)
180+ /// Create a configuration from a string.
181+ pub fn from_str ( content : & str ) -> std:: io:: Result < Config > {
182+ Config :: from_slice ( PathBuf :: from ( "-" ) , content. as_bytes ( ) )
149183 }
150184
151185 pub fn get_path ( & self ) -> & PathBuf {
@@ -218,4 +252,77 @@ mod tests {
218252 Config :: resolve_config_path( subdir_path. as_path( ) ) . unwrap( ) ,
219253 ) ;
220254 }
255+
256+ #[ test]
257+ fn config_defaults_start_addr ( ) {
258+ let config = Config :: from_str (
259+ r#"{
260+ "defaults": {
261+ "start": {
262+ "address": "localhost",
263+ "port": 8000
264+ }
265+ }
266+ }"# ,
267+ )
268+ . unwrap ( ) ;
269+
270+ assert_eq ! (
271+ config
272+ . get_config( )
273+ . get_defaults( )
274+ . get_start( )
275+ . get_binding_socket_addr( "1.2.3.4:123" )
276+ . unwrap( ) ,
277+ "localhost:8000" . to_socket_addrs( ) . unwrap( ) . next( ) . unwrap( )
278+ ) ;
279+ }
280+
281+ #[ test]
282+ fn config_defaults_start_addr_no_address ( ) {
283+ let config = Config :: from_str (
284+ r#"{
285+ "defaults": {
286+ "start": {
287+ "port": 8000
288+ }
289+ }
290+ }"# ,
291+ )
292+ . unwrap ( ) ;
293+
294+ assert_eq ! (
295+ config
296+ . get_config( )
297+ . get_defaults( )
298+ . get_start( )
299+ . get_binding_socket_addr( "1.2.3.4:123" )
300+ . unwrap( ) ,
301+ "1.2.3.4:8000" . to_socket_addrs( ) . unwrap( ) . next( ) . unwrap( )
302+ ) ;
303+ }
304+
305+ #[ test]
306+ fn config_defaults_start_addr_no_port ( ) {
307+ let config = Config :: from_str (
308+ r#"{
309+ "defaults": {
310+ "start": {
311+ "address": "localhost"
312+ }
313+ }
314+ }"# ,
315+ )
316+ . unwrap ( ) ;
317+
318+ assert_eq ! (
319+ config
320+ . get_config( )
321+ . get_defaults( )
322+ . get_start( )
323+ . get_binding_socket_addr( "1.2.3.4:123" )
324+ . unwrap( ) ,
325+ "localhost:123" . to_socket_addrs( ) . unwrap( ) . next( ) . unwrap( )
326+ ) ;
327+ }
221328}
0 commit comments