Skip to content

Suggests a design guideline for Config/Option structs

License

Notifications You must be signed in to change notification settings

desertbit/options

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Suggests a design guideline for Config/Option structs.

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.

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
}

About

Suggests a design guideline for Config/Option structs

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages