Default bool items not being set correctly when not present in config
vortexau opened this issue · 2 comments
Howdy,
According to the documentation:
A default key in the field tag makes fig fill the field with the value specified when the field is not otherwise set.
Given the following config.yaml
:
itemone:
enabled: false
With the following program:
package main
import (
"fmt"
"github.com/kkyr/fig"
)
type Config struct {
ItemOne ItemOne `default:{}`
ItemTwo ItemTwo `default:{}`
}
type ItemOne struct {
Enabled bool `fig:"enabled" default:true`
}
type ItemTwo struct {
Enabled bool `fig:"enabled" default:true`
}
func main() {
var conf Config
err := fig.Load(&conf)
if err != nil {
panic(err)
}
fmt.Printf("Config %+v", conf)
}
What was expected:
Field ItemTwo.Enabled
would be set to boolean true
.
What actually happened:
Field ItemTwo.Enabled
is set to boolean false
:
Config {ItemOne:{Enabled:false} ItemTwo:{Enabled:false}}
I've slimmed down an existing program to this most basic PoC to rule out other code in my application being a problem, though my usage is perhaps still incorrect.
Hi,
You should enclose struct tag values with quotes, i.e.:
type ItemOne struct {
Enabled bool `fig:"enabled" default:"true"`
}
But even doing that it won't work. It will, however, lead to an error:
panic: ItemOne.enabled: unable to set default: unsupported type: bool
This is because defaulting is not currently permitted for booleans, as described in the documentation. I'm pasting the relevant section here:
Note: the default setter knows if it should fill a field or not by comparing if the current value of the field is equal to the corresponding zero value for that field's type. This happens after the configuration is loaded and has the implication that the zero value set explicitly by the user will get overwritten by any default value registered for that field. It's for this reason that defaults on booleans are not permitted, as a boolean field with a default value of
true
would always be true (since if it were set to false it'd be overwritten).
It's not ideal but it's a current limitation of the fact that unset values are detected based on whether they're "zero" or not. A better solution, that would also accommodate for booleans, would be to keep track of what was explicitly set by the configuration and with that then determine whether a default value should be set or not. Though given that we're using an external library to set values (mapstructure) I don't see this as feasible without dropping the dependency and implementing own logic for loading a config.
Thanks for clarifying.