diff --git a/conf.v b/conf.v index c7a0e0d..65c0a16 100644 --- a/conf.v +++ b/conf.v @@ -17,20 +17,18 @@ pub struct LoadConfig { // looks for either `${env.prefix}${field_name.to_upper()}` or // `${env.prefix}${field_name.to_upper()}${env.file_suffix}`, returning the // contents of the file instead if the latter. If both or neither exist, the -// function returns an error. -fn (ld LoadConfig) get_env_var(field_name string) !string { +// function returns an error. It returns two values, with the first indicating +// whether the env vars were actually present. +fn (ld LoadConfig) get_env_var(field_name string) !(bool, string) { env_var_name := '$ld.prefix$field_name.to_upper()' env_file_name := '$ld.prefix$field_name.to_upper()$ld.file_suffix' - env_var := ld.env[env_var_name] or { '' } - env_file := ld.env[env_file_name] or { '' } - // If both are missing, we return an empty string - if env_var == '' && env_file == '' { - return '' + if env_var_name !in ld.env && env_file_name !in ld.env { + return false, '' } // If they're both set, we report a conflict - if env_var != '' && env_file != '' { + if env_var_name in ld.env && env_file_name in ld.env { return error('Only one of $env_var_name or $env_file_name can be defined.') } @@ -38,12 +36,12 @@ fn (ld LoadConfig) get_env_var(field_name string) !string { // I'm pretty sure this also prevents variable ending in _FILE (e.g. // VIETER_LOG_FILE) from being mistakingely read as an _FILE suffixed env // var. - if env_var != '' { - return env_var + if env_var_name in ld.env { + return true, ld.env[env_var_name] } // Otherwise, we process the file - return os.read_file(env_file) or { + return true, os.read_file(ld.env[env_file_name]) or { error('Failed to read file defined in $env_file_name: ${err.msg()}.') } } @@ -86,11 +84,11 @@ pub fn load(ld LoadConfig) !T { } $for field in T.fields { - env_value := ld.get_env_var(field.name)! + env_present, env_value := ld.get_env_var(field.name)! // The value of an env var will always take precedence over the toml // file. - if env_value != '' { + if env_present { $if field.typ is string { res.$(field.name) = env_value } $else $if field.typ is int { diff --git a/string_test.v b/string_test.v index b91cff5..46cb85d 100644 --- a/string_test.v +++ b/string_test.v @@ -8,29 +8,47 @@ struct SingleConfDefault { some_string string = 'default' } -const env = { - 'SOME_STRING': 'env' -} - -const prefix_env = { - 'TEST_SOME_STRING': 'env' -} - fn test_string_present_no_default() { conf := load(default_path: 'test/string.toml')! assert conf == SingleConf{ some_string: 'hi' } + + conf2 := load(default_path: 'test/string_empty.toml')! + assert conf2 == SingleConf{ + some_string: '' + } } fn test_string_present_no_default_env() { - conf := load(default_path: 'test/string.toml', env: .env)! + mut conf := load( + default_path: 'test/string.toml' + env: { + 'SOME_STRING': 'env' + } + )! assert conf == SingleConf{ some_string: 'env' } - conf2 := load(default_path: 'test/string.toml', env: .prefix_env, prefix: 'TEST_')! - assert conf2 == SingleConf{ + conf = load( + default_path: 'test/string.toml' + env: { + 'SOME_STRING': '' + } + )! + assert conf == SingleConf{ + some_string: '' + } + + conf = load( + default_path: 'test/string.toml' + env: { + 'TEST_SOME_STRING': 'env' + } + prefix: 'TEST_' + )! + assert conf == SingleConf{ some_string: 'env' } } @@ -41,13 +59,34 @@ fn test_string_absent_no_default() { } fn test_string_absent_no_default_env() { - conf := load(default_path: 'test/string.toml', env: .env)! + mut conf := load( + default_path: 'test/string.toml' + env: { + 'SOME_STRING': 'env' + } + )! assert conf == SingleConf{ some_string: 'env' } - conf2 := load(default_path: 'test/string.toml', env: .prefix_env, prefix: 'TEST_')! - assert conf2 == SingleConf{ + conf = load( + default_path: 'test/string.toml' + env: { + 'SOME_STRING': '' + } + )! + assert conf == SingleConf{ + some_string: '' + } + + conf = load( + default_path: 'test/string.toml' + env: { + 'TEST_SOME_STRING': 'env' + } + prefix: 'TEST_' + )! + assert conf == SingleConf{ some_string: 'env' } } @@ -60,17 +99,34 @@ fn test_string_present_default() { } fn test_string_present_default_env() { - conf := load(default_path: 'test/string.toml', env: .env)! + mut conf := load( + default_path: 'test/string.toml' + env: { + 'SOME_STRING': 'env' + } + )! assert conf == SingleConfDefault{ some_string: 'env' } - conf2 := load( + conf = load( default_path: 'test/string.toml' - env: .prefix_env + env: { + 'SOME_STRING': '' + } + )! + assert conf == SingleConfDefault{ + some_string: '' + } + + conf = load( + default_path: 'test/string.toml' + env: { + 'TEST_SOME_STRING': 'env' + } prefix: 'TEST_' )! - assert conf2 == SingleConfDefault{ + assert conf == SingleConfDefault{ some_string: 'env' } } @@ -83,17 +139,34 @@ fn test_string_absent_default() { } fn test_string_absent_default_env() { - conf := load(default_path: 'test/empty.toml', env: .env)! + mut conf := load( + default_path: 'test/empty.toml' + env: { + 'SOME_STRING': 'env' + } + )! assert conf == SingleConfDefault{ some_string: 'env' } - conf2 := load( + conf = load( default_path: 'test/empty.toml' - env: .prefix_env + env: { + 'SOME_STRING': '' + } + )! + assert conf == SingleConfDefault{ + some_string: '' + } + + conf = load( + default_path: 'test/empty.toml' + env: { + 'TEST_SOME_STRING': 'env' + } prefix: 'TEST_' )! - assert conf2 == SingleConfDefault{ + assert conf == SingleConfDefault{ some_string: 'env' } } diff --git a/test/int.toml b/test/int.toml new file mode 100644 index 0000000..263b0ce --- /dev/null +++ b/test/int.toml @@ -0,0 +1 @@ +some_int = "hi" diff --git a/test/string_empty.toml b/test/string_empty.toml new file mode 100644 index 0000000..8866b17 --- /dev/null +++ b/test/string_empty.toml @@ -0,0 +1 @@ +some_string = ""