feat: add bool type

main
Jef Roosens 2022-12-28 20:04:45 +01:00
parent 5fd74631eb
commit fca58e3da0
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
5 changed files with 188 additions and 6 deletions

171
bool_test.v 100644
View File

@ -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<SingleConf>(default_path: 'test/bool.toml')!
assert conf == SingleConf{
some_bool: true
}
}
fn test_bool_present_no_default_env() {
mut conf_f := load<SingleConfDefaultFalse>(
default_path: 'test/bool.toml'
env: {
'SOME_BOOL': '1'
}
)!
assert conf_f == SingleConfDefaultFalse{
some_bool: true
}
mut conf_t := load<SingleConfDefaultTrue>(
default_path: 'test/bool.toml'
env: {
'SOME_BOOL': ''
}
)!
assert conf_t == SingleConfDefaultTrue{
some_bool: false
}
conf_f = load<SingleConfDefaultFalse>(
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<SingleConf>(default_path: 'test/empty.toml') or { return }
assert false
}
fn test_bool_absent_no_default_env() {
mut conf_f := load<SingleConfDefaultFalse>(
default_path: 'test/bool.toml'
env: {
'SOME_BOOL': '1'
}
)!
assert conf_f == SingleConfDefaultFalse{
some_bool: true
}
mut conf_t := load<SingleConfDefaultTrue>(
default_path: 'test/bool.toml'
env: {
'SOME_BOOL': ''
}
)!
assert conf_t == SingleConfDefaultTrue{
some_bool: false
}
conf_f = load<SingleConfDefaultFalse>(
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<SingleConfDefaultFalse>(default_path: 'test/bool.toml')!
assert conf == SingleConfDefaultFalse{
some_bool: true
}
}
fn test_bool_present_default_env() {
mut conf_f := load<SingleConfDefaultFalse>(
default_path: 'test/bool.toml'
env: {
'SOME_BOOL': '1'
}
)!
assert conf_f == SingleConfDefaultFalse{
some_bool: true
}
mut conf_t := load<SingleConfDefaultTrue>(
default_path: 'test/bool.toml'
env: {
'SOME_BOOL': ''
}
)!
assert conf_t == SingleConfDefaultTrue{
some_bool: false
}
conf_f = load<SingleConfDefaultFalse>(
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<SingleConfDefaultTrue>(default_path: 'test/empty.toml')!
assert conf == SingleConfDefaultTrue{
some_bool: true
}
}
fn test_bool_absent_default_env() {
mut conf_f := load<SingleConfDefaultFalse>(
default_path: 'test/empty.toml'
env: {
'SOME_BOOL': '1'
}
)!
assert conf_f == SingleConfDefaultFalse{
some_bool: true
}
mut conf_t := load<SingleConfDefaultTrue>(
default_path: 'test/empty.toml'
env: {
'SOME_BOOL': ''
}
)!
assert conf_t == SingleConfDefaultTrue{
some_bool: false
}
conf_f = load<SingleConfDefaultFalse>(
default_path: 'test/empty.toml'
env: {
'TEST_SOME_BOOL': 'true'
}
prefix: 'TEST_'
)!
assert conf_f == SingleConfDefaultFalse{
some_bool: true
}
}

12
conf.v
View File

@ -53,7 +53,7 @@ fn (ld LoadConfig) get_env_var(field_name string) !(bool, string) {
pub fn load<T>(ld LoadConfig) !T { pub fn load<T>(ld LoadConfig) !T {
// Ensure all struct fields consist of supported types // Ensure all struct fields consist of supported types
$for field in T.fields { $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 { } $else {
// I'd prefer changing this to $compile_error, but as of V 0.3.2, // 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 // this seems to be bugged. If I replace this call with a
@ -84,6 +84,8 @@ pub fn load<T>(ld LoadConfig) !T {
res.$(field.name) = s.string() res.$(field.name) = s.string()
} $else $if field.typ is int { } $else $if field.typ is int {
res.$(field.name) = s.int() res.$(field.name) = s.int()
} $else $if field.typ is bool {
res.$(field.name) = s.bool()
} }
has_value.add(field.name) has_value.add(field.name)
@ -101,6 +103,10 @@ pub fn load<T>(ld LoadConfig) !T {
res.$(field.name) = env_value res.$(field.name) = env_value
} $else $if field.typ is int { } $else $if field.typ is int {
res.$(field.name) = env_value.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) has_value.add(field.name)
@ -118,6 +124,10 @@ pub fn load<T>(ld LoadConfig) !T {
has_default = res.$(field.name) != '' has_default = res.$(field.name) != ''
} $else $if field.typ is int { } $else $if field.typ is int {
has_default = res.$(field.name) != 0 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 { if has_default {

View File

@ -182,7 +182,7 @@ fn test_int_absent_default_empty() {
} }
} }
/* fn test_int_wrong_type() { */ // fn test_int_wrong_type() {
/* conf := load<SingleConf>(default_path: 'test/int_wrong_type.toml') or { return } */ // conf := load<SingleConf>(default_path: 'test/int_wrong_type.toml') or { return }
/* assert false */ // assert false
/* } */ //}

1
test/bool.toml 100644
View File

@ -0,0 +1 @@
some_bool = true