nix-amer/internal/cnf/ini.go

111 lines
2.0 KiB
Go

package cnf
import (
lib "github.com/go-ini/ini"
"io"
"io/ioutil"
"strings"
)
type ini struct {
sections []string
data *lib.File
parsed bool
}
// ReadFrom implements io.ReaderFrom
func (d *ini) ReadFrom(_reader io.Reader) (int64, error) {
// disallow "key: value"
// when trying to find out the format from content
// and avoids conflicts with YAML
opts := lib.LoadOptions{
KeyValueDelimiters: "=",
}
file, err := lib.LoadSources(opts, ioutil.NopCloser(_reader))
// 1. get json decoder
if err != nil {
return 0, err
}
d.data = file
d.sections = file.SectionStrings()
d.parsed = true
return 0, nil
}
// WriteTo implements io.WriterTo
func (d *ini) WriteTo(_writer io.Writer) (int64, error) {
return d.data.WriteTo(_writer)
}
// Get returns the value of a dot-separated path, and if it exists
// the maximum depth is 2 : Section.Field
func (d *ini) Get(_path string) (string, bool) {
// 1. split path
path := strings.Split(_path, ".")
// 2. fail if too long
if len(path) > 2 {
return "", false
}
// 3. direct field (no section)
if len(path) == 1 {
// unknown field
if !d.data.Section("").Haskey(path[0]) {
return "", false
}
// found
return d.data.Section("").Key(path[0]).String(), true
}
// 4. fail on missing section
found := false
for _, sec := range d.sections {
if sec == path[0] {
found = true
break
}
}
if !found {
return "", false
}
// 5. Fail on unknown field
if !d.data.Section(path[0]).HasKey(path[1]) {
return "", false
}
// 6. return value
return d.data.Section(path[0]).Key(path[1]).String(), true
}
// Set the value of a dot-separated path, and creates it if not found
func (d *ini) Set(_path, _value string) bool {
// 1. split path
path := strings.Split(_path, ".")
// 2. fail if too long
if len(path) > 2 {
return false
}
// 3. direct field (no section)
section, field := "", path[0]
if len(path) > 1 {
section, field = path[0], path[1]
}
// 4. Set field value
d.data.Section(section).Key(field).SetValue(_value)
return true
}