diff --git a/bool_test.v b/bool_test.v new file mode 100644 index 0000000..1418bde --- /dev/null +++ b/bool_test.v @@ -0,0 +1,171 @@ +module conf + +struct SingleConf { + some_bool bool +} + +struct SingleConfDefaultFalse { + some_bool bool [empty_default] +} + +struct SingleConfDefaultTrue { + some_bool bool = true +} + +fn test_bool_present_no_default() { + mut conf := load(default_path: 'test/bool.toml')! + assert conf == SingleConf{ + some_bool: true + } +} + +fn test_bool_present_no_default_env() { + mut conf_f := load( + default_path: 'test/bool.toml' + env: { + 'SOME_BOOL': '1' + } + )! + assert conf_f == SingleConfDefaultFalse{ + some_bool: true + } + + mut conf_t := load( + default_path: 'test/bool.toml' + env: { + 'SOME_BOOL': '' + } + )! + assert conf_t == SingleConfDefaultTrue{ + some_bool: false + } + + conf_f = load( + default_path: 'test/bool.toml' + env: { + 'TEST_SOME_BOOL': 'true' + } + prefix: 'TEST_' + )! + assert conf_f == SingleConfDefaultFalse{ + some_bool: true + } +} + +fn test_bool_absent_no_default() { + conf := load(default_path: 'test/empty.toml') or { return } + assert false +} + +fn test_bool_absent_no_default_env() { + mut conf_f := load( + default_path: 'test/bool.toml' + env: { + 'SOME_BOOL': '1' + } + )! + assert conf_f == SingleConfDefaultFalse{ + some_bool: true + } + + mut conf_t := load( + default_path: 'test/bool.toml' + env: { + 'SOME_BOOL': '' + } + )! + assert conf_t == SingleConfDefaultTrue{ + some_bool: false + } + + conf_f = load( + default_path: 'test/bool.toml' + env: { + 'TEST_SOME_BOOL': '1' + } + prefix: 'TEST_' + )! + assert conf_f == SingleConfDefaultFalse{ + some_bool: true + } +} + +fn test_bool_present_default() { + conf := load(default_path: 'test/bool.toml')! + assert conf == SingleConfDefaultFalse{ + some_bool: true + } +} + +fn test_bool_present_default_env() { + mut conf_f := load( + default_path: 'test/bool.toml' + env: { + 'SOME_BOOL': '1' + } + )! + assert conf_f == SingleConfDefaultFalse{ + some_bool: true + } + + mut conf_t := load( + default_path: 'test/bool.toml' + env: { + 'SOME_BOOL': '' + } + )! + assert conf_t == SingleConfDefaultTrue{ + some_bool: false + } + + conf_f = load( + default_path: 'test/bool.toml' + env: { + 'TEST_SOME_BOOL': '1' + } + prefix: 'TEST_' + )! + assert conf_f == SingleConfDefaultFalse{ + some_bool: true + } +} + +fn test_bool_absent_default() { + conf := load(default_path: 'test/empty.toml')! + assert conf == SingleConfDefaultTrue{ + some_bool: true + } +} + +fn test_bool_absent_default_env() { + mut conf_f := load( + default_path: 'test/empty.toml' + env: { + 'SOME_BOOL': '1' + } + )! + assert conf_f == SingleConfDefaultFalse{ + some_bool: true + } + + mut conf_t := load( + default_path: 'test/empty.toml' + env: { + 'SOME_BOOL': '' + } + )! + assert conf_t == SingleConfDefaultTrue{ + some_bool: false + } + + conf_f = load( + default_path: 'test/empty.toml' + env: { + 'TEST_SOME_BOOL': 'true' + } + prefix: 'TEST_' + )! + assert conf_f == SingleConfDefaultFalse{ + some_bool: true + } +} diff --git a/conf.v b/conf.v index f92361d..cf2405e 100644 --- a/conf.v +++ b/conf.v @@ -53,7 +53,7 @@ fn (ld LoadConfig) get_env_var(field_name string) !(bool, string) { pub fn load(ld LoadConfig) !T { // Ensure all struct fields consist of supported types $for field in T.fields { - $if field.typ is string || field.typ is int { + $if field.typ is string || field.typ is int || field.typ is bool { } $else { // I'd prefer changing this to $compile_error, but as of V 0.3.2, // this seems to be bugged. If I replace this call with a @@ -84,6 +84,8 @@ pub fn load(ld LoadConfig) !T { res.$(field.name) = s.string() } $else $if field.typ is int { res.$(field.name) = s.int() + } $else $if field.typ is bool { + res.$(field.name) = s.bool() } has_value.add(field.name) @@ -101,6 +103,10 @@ pub fn load(ld LoadConfig) !T { res.$(field.name) = env_value } $else $if field.typ is int { res.$(field.name) = env_value.int() + } $else $if field.typ is bool { + // Env var accepts '1' and 'true' as truthy, everything else + // evaluates to false + res.$(field.name) = env_value in ['1', 'true'] } has_value.add(field.name) @@ -118,6 +124,10 @@ pub fn load(ld LoadConfig) !T { has_default = res.$(field.name) != '' } $else $if field.typ is int { has_default = res.$(field.name) != 0 + } $else $if field.typ is bool { + // This explicit comparison is required as the type system gets + // a bit confused otherwise + has_default = res.$(field.name) == true } if has_default { diff --git a/conf_test.v b/conf_test.v index edc985f..4877724 100644 --- a/conf_test.v +++ b/conf_test.v @@ -1,7 +1,7 @@ module conf struct WrongTypeConfig { - f map[string]string + f map[string]string } fn test_wrong_type() { diff --git a/int_test.v b/int_test.v index f02ef9e..defddc8 100644 --- a/int_test.v +++ b/int_test.v @@ -182,7 +182,7 @@ fn test_int_absent_default_empty() { } } -/* fn test_int_wrong_type() { */ -/* conf := load(default_path: 'test/int_wrong_type.toml') or { return } */ -/* assert false */ -/* } */ +// fn test_int_wrong_type() { +// conf := load(default_path: 'test/int_wrong_type.toml') or { return } +// assert false +//} diff --git a/test/bool.toml b/test/bool.toml new file mode 100644 index 0000000..a3e45e2 --- /dev/null +++ b/test/bool.toml @@ -0,0 +1 @@ +some_bool = true