@@ -68,6 +68,7 @@ impl ForgeEnvironmentInfra {
6868 stdout_max_prefix_length : 200 ,
6969 stdout_max_suffix_length : 200 ,
7070 tool_timeout : parse_env :: < u64 > ( "FORGE_TOOL_TIMEOUT" ) . unwrap_or ( 300 ) ,
71+ auto_open_dump : parse_env :: < bool > ( "FORGE_DUMP_AUTO_OPEN" ) . unwrap_or ( false ) ,
7172 stdout_max_line_length : parse_env :: < usize > ( "FORGE_STDOUT_MAX_LINE_LENGTH" )
7273 . unwrap_or ( 2000 ) ,
7374 http : resolve_http_config ( ) ,
@@ -109,11 +110,49 @@ impl EnvironmentInfra for ForgeEnvironmentInfra {
109110 }
110111}
111112
112- fn parse_env < T : FromStr > ( name : & str ) -> Option < T > {
113+ /// Trait for parsing environment variable values with custom logic for
114+ /// different types
115+ trait FromEnvStr : Sized {
116+ fn from_env_str ( s : & str ) -> Option < Self > ;
117+ }
118+
119+ /// Custom implementation for bool with support for multiple truthy values
120+ /// Supports: "true", "1", "yes" (case-insensitive) as true; everything else as
121+ /// false
122+ impl FromEnvStr for bool {
123+ fn from_env_str ( s : & str ) -> Option < Self > {
124+ Some ( matches ! ( s. to_lowercase( ) . as_str( ) , "true" | "1" | "yes" ) )
125+ }
126+ }
127+
128+ // Macro to implement FromEnvStr for types that already implement FromStr
129+ macro_rules! impl_from_env_str_via_from_str {
130+ ( $( $t: ty) ,* $( , ) ?) => {
131+ $(
132+ impl FromEnvStr for $t {
133+ fn from_env_str( s: & str ) -> Option <Self > {
134+ <$t as FromStr >:: from_str( s) . ok( )
135+ }
136+ }
137+ ) *
138+ } ;
139+ }
140+
141+ // Implement FromEnvStr for commonly used types
142+ impl_from_env_str_via_from_str ! {
143+ u8 , u16 , u32 , u64 , u128 , usize ,
144+ i8 , i16 , i32 , i64 , i128 , isize ,
145+ f32 , f64 ,
146+ String ,
147+ forge_domain:: TlsBackend ,
148+ forge_domain:: TlsVersion ,
149+ }
150+
151+ /// Parse environment variable using custom FromEnvStr trait
152+ fn parse_env < T : FromEnvStr > ( name : & str ) -> Option < T > {
113153 std:: env:: var ( name)
114- . as_ref ( )
115154 . ok ( )
116- . and_then ( |var | T :: from_str ( var ) . ok ( ) )
155+ . and_then ( |val | T :: from_env_str ( & val ) )
117156}
118157
119158/// Resolves retry configuration from environment variables or returns defaults
@@ -469,6 +508,94 @@ mod tests {
469508 }
470509 }
471510
511+ #[ test]
512+ #[ serial]
513+ fn test_auto_open_dump_env_var ( ) {
514+ let cwd = tempdir ( ) . unwrap ( ) . path ( ) . to_path_buf ( ) ;
515+ let infra = ForgeEnvironmentInfra :: new ( false , cwd) ;
516+
517+ // Test default value when env var is not set
518+ {
519+ unsafe {
520+ env:: remove_var ( "FORGE_DUMP_AUTO_OPEN" ) ;
521+ }
522+ let env = infra. get_environment ( ) ;
523+ assert_eq ! ( env. auto_open_dump, false ) ;
524+ }
525+
526+ // Test enabled with "true"
527+ {
528+ unsafe {
529+ env:: set_var ( "FORGE_DUMP_AUTO_OPEN" , "true" ) ;
530+ }
531+ let env = infra. get_environment ( ) ;
532+ assert_eq ! ( env. auto_open_dump, true ) ;
533+ unsafe {
534+ env:: remove_var ( "FORGE_DUMP_AUTO_OPEN" ) ;
535+ }
536+ }
537+
538+ // Test enabled with "1"
539+ {
540+ unsafe {
541+ env:: set_var ( "FORGE_DUMP_AUTO_OPEN" , "1" ) ;
542+ }
543+ let env = infra. get_environment ( ) ;
544+ assert_eq ! ( env. auto_open_dump, true ) ;
545+ unsafe {
546+ env:: remove_var ( "FORGE_DUMP_AUTO_OPEN" ) ;
547+ }
548+ }
549+
550+ // Test case insensitive "TRUE"
551+ {
552+ unsafe {
553+ env:: set_var ( "FORGE_DUMP_AUTO_OPEN" , "TRUE" ) ;
554+ }
555+ let env = infra. get_environment ( ) ;
556+ assert_eq ! ( env. auto_open_dump, true ) ;
557+ unsafe {
558+ env:: remove_var ( "FORGE_DUMP_AUTO_OPEN" ) ;
559+ }
560+ }
561+
562+ // Test disabled with "false"
563+ {
564+ unsafe {
565+ env:: set_var ( "FORGE_DUMP_AUTO_OPEN" , "false" ) ;
566+ }
567+ let env = infra. get_environment ( ) ;
568+ assert_eq ! ( env. auto_open_dump, false ) ;
569+ unsafe {
570+ env:: remove_var ( "FORGE_DUMP_AUTO_OPEN" ) ;
571+ }
572+ }
573+
574+ // Test disabled with "0"
575+ {
576+ unsafe {
577+ env:: set_var ( "FORGE_DUMP_AUTO_OPEN" , "0" ) ;
578+ }
579+ let env = infra. get_environment ( ) ;
580+ assert_eq ! ( env. auto_open_dump, false ) ;
581+ unsafe {
582+ env:: remove_var ( "FORGE_DUMP_AUTO_OPEN" ) ;
583+ }
584+ }
585+
586+ // Test fallback to default for invalid value
587+ {
588+ unsafe {
589+ env:: set_var ( "FORGE_DUMP_AUTO_OPEN" , "invalid" ) ;
590+ }
591+ let env = infra. get_environment ( ) ;
592+ assert_eq ! ( env. auto_open_dump, false ) ;
593+ unsafe {
594+ env:: remove_var ( "FORGE_DUMP_AUTO_OPEN" ) ;
595+ }
596+ }
597+ }
598+
472599 #[ test]
473600 #[ serial]
474601 fn test_tool_timeout_env_var ( ) {
@@ -508,4 +635,50 @@ mod tests {
508635 }
509636 }
510637 }
638+ #[ test]
639+ #[ serial]
640+ fn test_unified_parse_env_functionality ( ) {
641+ // Test that the unified parse_env works for different types
642+
643+ // Test boolean parsing with custom logic
644+ unsafe {
645+ env:: set_var ( "TEST_BOOL_TRUE" , "yes" ) ;
646+ env:: set_var ( "TEST_BOOL_FALSE" , "no" ) ;
647+ }
648+
649+ assert_eq ! ( parse_env:: <bool >( "TEST_BOOL_TRUE" ) , Some ( true ) ) ;
650+ assert_eq ! ( parse_env:: <bool >( "TEST_BOOL_FALSE" ) , Some ( false ) ) ;
651+
652+ // Test numeric parsing
653+ unsafe {
654+ env:: set_var ( "TEST_U64" , "123" ) ;
655+ env:: set_var ( "TEST_F64" , "45.67" ) ;
656+ }
657+
658+ assert_eq ! ( parse_env:: <u64 >( "TEST_U64" ) , Some ( 123 ) ) ;
659+ assert_eq ! ( parse_env:: <f64 >( "TEST_F64" ) , Some ( 45.67 ) ) ;
660+
661+ // Test string parsing
662+ unsafe {
663+ env:: set_var ( "TEST_STRING" , "hello world" ) ;
664+ }
665+
666+ assert_eq ! (
667+ parse_env:: <String >( "TEST_STRING" ) ,
668+ Some ( "hello world" . to_string( ) )
669+ ) ;
670+
671+ // Test missing env var
672+ assert_eq ! ( parse_env:: <bool >( "NONEXISTENT_VAR" ) , None ) ;
673+ assert_eq ! ( parse_env:: <u64 >( "NONEXISTENT_VAR" ) , None ) ;
674+
675+ // Clean up
676+ unsafe {
677+ env:: remove_var ( "TEST_BOOL_TRUE" ) ;
678+ env:: remove_var ( "TEST_BOOL_FALSE" ) ;
679+ env:: remove_var ( "TEST_U64" ) ;
680+ env:: remove_var ( "TEST_F64" ) ;
681+ env:: remove_var ( "TEST_STRING" ) ;
682+ }
683+ }
511684}
0 commit comments