https://github.com/desertbit/options
Suggests a design guideline for Config/Option structs
https://github.com/desertbit/options
Last synced: 6 months ago
JSON representation
Suggests a design guideline for Config/Option structs
- Host: GitHub
- URL: https://github.com/desertbit/options
- Owner: desertbit
- License: mit
- Created: 2020-06-09T08:46:54.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2021-01-26T15:38:17.000Z (over 5 years ago)
- Last Synced: 2023-12-16T05:19:36.434Z (over 2 years ago)
- Language: Go
- Size: 15.6 KB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
Suggests a design guideline for Config/Option structs.
```go
type Options struct {
NumWorkers int `yaml:"num-workers,omitempty"`
Name string `yaml:"name,omitempty"`
ConfThreshold int `yaml:"conf-threshold,omitempty"`
}
func DefaultOptions() Options {
return Options{
NumWorkers: 8,
Name: "testName",
ConfThreshold: 0.85,
}
}
func (o Options) Save(path string) error {
// Do not serialize any values that match the default values.
// This way, only changes are reflected in the options file.
// The Options struct itself is not altered, since the receiver
// is not a pointer.
err = options.StripDefaults(&o, DefaultOptions())
if err != nil {
return err
}
// ... yaml marshal and write to file ...
}
```
The main concept is **simplicity**. One simple Options struct combined with one constructor that returns the default settings.
By not serializing any default values (`StripDefaults`), we keep the written file tidy and only list **changes to the defaults**.
In case a **slice** or **map** is used in the config, whose elements are structs again, it is not possible to state real default values.
Instead, one should iterate over the options after parsing and set default values on each of the elements.
```go
type Options struct {
NumWorkers int `yaml:"num-workers,omitempty"`
Name string `yaml:"name,omitempty"`
ConfThreshold int `yaml:"conf-threshold,omitempty"`
Sl []Nested `yaml:"sl,omitempty"`
}
type Nested struct {
Test int `yaml:"test,omitempty"`
}
func DefaultNestedOptions() Nested {
return Nested{Test: 5}
}
func ParseOptionsFromFile(path string) (o Options, err error) {
o = DefaultOptions(path)
// Read data from file.
data, err := ioutil.ReadFile(path)
if err != nil {
return
}
// Unmarshal the data.
err = yaml.UnmarshalStrict(data, &o)
if err != nil {
return
}
// Iterate over the nested options and set default values.
dn := DefaultNestedOptions()
for i := range o.Sl {
err = options.SetDefaults(o.Sl[i], dn)
if err != nil {
return
}
}
return
}
```