package cnf import ( "github.com/go-ini/ini" "io" "io/ioutil" "strings" ) type Ini struct { sections []string data *ini.File parsed bool } // Read extract a reader as its JSON representation func (d *Ini) Read(_reader io.Reader) error { // 1. get json decoder file, err := ini.Load(ioutil.NopCloser(_reader)) if err != nil { return err } d.data = file d.sections = file.SectionStrings() d.parsed = true return nil } // Write the INI representation to a writer func (d *Ini) Write(_writer io.Writer) error { _, err := d.data.WriteTo(_writer) return err } // 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 }