@@ -85,35 +85,34 @@ impl Default for Config {
85
85
86
86
impl Config {
87
87
pub fn from_env ( ) -> Result < Self > {
88
- fn require_env_var ( var_key : & ' static str ) -> Result < String > {
89
- std:: env:: var ( var_key) . map_err ( |_| eyre ! ( "The \" {}\" env var must be set or a configuration file must be specified" , var_key) )
90
- }
88
+ Self :: from_vars ( |key| std:: env:: var ( key) . ok ( ) )
89
+ }
90
+
91
+ fn from_vars < F > ( get : F ) -> Result < Self >
92
+ where
93
+ F : Fn ( & ' static str ) -> Option < String > + ' static ,
94
+ {
95
+ let require = |var_key : & ' static str | {
96
+ get ( var_key) . ok_or_else ( || eyre ! ( "The \" {}\" env var must be set or a configuration file must be specified" , var_key) )
97
+ } ;
91
98
92
99
Ok ( Self {
93
- network : Network :: from_str (
94
- & std:: env:: var ( "NETWORK" ) . unwrap_or_default ( ) ,
95
- )
96
- . unwrap_or ( Network :: MAINNET ) ,
97
- eth_execution_rpc : require_env_var ( "ETH_EXECUTION_RPC" ) ?,
98
- starknet_rpc : require_env_var ( "STARKNET_RPC" ) ?,
99
- data_dir : PathBuf :: from (
100
- std:: env:: var ( "DATA_DIR" ) . unwrap_or_default ( ) ,
101
- ) ,
102
- poll_secs : u64:: from_str (
103
- & std:: env:: var ( "POLL_SECS" ) . unwrap_or_default ( ) ,
104
- )
105
- . unwrap_or ( DEFAULT_POLL_SECS ) ,
106
- rpc_addr : if let Ok ( addr) = std:: env:: var ( "RPC_ADDR" ) {
107
- SocketAddr :: from_str ( & addr)
108
- . context ( "Invalid value for `RPC_ADDR`" ) ?
109
- } else {
110
- rpc_addr ( )
100
+ network : Network :: from_str ( & get ( "NETWORK" ) . unwrap_or_default ( ) )
101
+ . unwrap_or ( Network :: MAINNET ) ,
102
+ eth_execution_rpc : require ( "ETH_EXECUTION_RPC" ) ?,
103
+ starknet_rpc : require ( "STARKNET_RPC" ) ?,
104
+ data_dir : PathBuf :: from ( get ( "DATA_DIR" ) . unwrap_or_default ( ) ) ,
105
+ poll_secs : u64:: from_str ( & get ( "POLL_SECS" ) . unwrap_or_default ( ) )
106
+ . unwrap_or ( DEFAULT_POLL_SECS ) ,
107
+ rpc_addr : match get ( "RPC_ADDR" ) {
108
+ Some ( addr) => SocketAddr :: from_str ( & addr)
109
+ . context ( "Invalid value for `RPC_ADDR`" ) ?,
110
+ None => rpc_addr ( ) ,
111
111
} ,
112
- fee_token_addr : if let Ok ( addr) = std:: env:: var ( "FEE_TOKEN_ADDR" ) {
113
- FieldElement :: from_hex_be ( & addr)
114
- . context ( "Invalid value for `FEE_TOKEN_ADDR`" ) ?
115
- } else {
116
- fee_token_addr ( )
112
+ fee_token_addr : match get ( "FEE_TOKEN_ADDR" ) {
113
+ Some ( addr) => FieldElement :: from_hex_be ( & addr)
114
+ . context ( "Invalid value for `FEE_TOKEN_ADDR`" ) ?,
115
+ None => fee_token_addr ( ) ,
117
116
} ,
118
117
} )
119
118
}
@@ -214,3 +213,71 @@ impl Config {
214
213
. expect ( "incorrect helios client config" )
215
214
}
216
215
}
216
+
217
+ #[ cfg( test) ]
218
+ mod tests {
219
+ use std:: collections:: HashMap ;
220
+
221
+ use super :: * ;
222
+
223
+ fn case ( vars : & [ ( & ' static str , & ' static str ) ] ) -> Result < Config > {
224
+ let vars: HashMap < & str , & str > = HashMap :: from_iter ( vars. to_vec ( ) ) ;
225
+ Config :: from_vars ( move |s| vars. get ( s) . map ( |s| s. to_string ( ) ) )
226
+ }
227
+
228
+ static MIN_CONFIG_VARS : & [ ( & ' static str , & ' static str ) ] =
229
+ & [ ( "ETH_EXECUTION_RPC" , "url" ) , ( "STARKNET_RPC" , "url" ) ] ;
230
+
231
+ #[ test]
232
+ fn test_min_config_requirements ( ) {
233
+ assert ! ( case( & [ ( "ETH_EXECUTION_RPC" , "url" ) , ] ) . is_err( ) ) ;
234
+ assert ! ( case( & [ ( "STARKNET_RPC" , "url" ) , ] ) . is_err( ) ) ;
235
+
236
+ assert ! ( case( & MIN_CONFIG_VARS ) . is_ok( ) ) ;
237
+ }
238
+
239
+ #[ test]
240
+ fn test_unspecified_network_is_mainnet ( ) {
241
+ let config = case ( & MIN_CONFIG_VARS ) . unwrap ( ) ;
242
+ assert_eq ! ( config. network, Network :: MAINNET ) ;
243
+ }
244
+
245
+ #[ test]
246
+ fn test_rpc_address_is_validated ( ) {
247
+ let result = case ( & [
248
+ ( "ETH_EXECUTION_RPC" , "url" ) ,
249
+ ( "STARKNET_RPC" , "url" ) ,
250
+ ( "RPC_ADDR" , "invalid_value" ) ,
251
+ ] ) ;
252
+ assert ! ( result. is_err( ) ) ;
253
+
254
+ let result = case ( & [
255
+ ( "ETH_EXECUTION_RPC" , "url" ) ,
256
+ ( "STARKNET_RPC" , "url" ) ,
257
+ ( "RPC_ADDR" , "127.0.0.1:3333" ) ,
258
+ ] ) ;
259
+ assert ! ( result. is_ok( ) ) ;
260
+ assert_eq ! (
261
+ SocketAddr :: from_str( "127.0.0.1:3333" ) . unwrap( ) ,
262
+ result. unwrap( ) . rpc_addr
263
+ ) ;
264
+ }
265
+
266
+ #[ test]
267
+ fn test_fee_token_addr_is_validated ( ) {
268
+ let result = case ( & [
269
+ ( "ETH_EXECUTION_RPC" , "url" ) ,
270
+ ( "STARKNET_RPC" , "url" ) ,
271
+ ( "FEE_TOKEN_ADDR" , "invalid_value" ) ,
272
+ ] ) ;
273
+ assert ! ( result. is_err( ) ) ;
274
+
275
+ let result = case ( & [
276
+ ( "ETH_EXECUTION_RPC" , "url" ) ,
277
+ ( "STARKNET_RPC" , "url" ) ,
278
+ ( "FEE_TOKEN_ADDR" , "1" ) ,
279
+ ] ) ;
280
+ assert ! ( result. is_ok( ) ) ;
281
+ assert_eq ! ( FieldElement :: ONE , result. unwrap( ) . fee_token_addr) ;
282
+ }
283
+ }
0 commit comments