From 5c8eb602f1c9d28db1035567ffc97b06cedc68c2 Mon Sep 17 00:00:00 2001 From: Shulhan Date: Tue, 21 May 2019 23:19:36 +0700 Subject: ini: add method to convert key-value to map AsMap return the INI contents as mapping of (section "." subsection "." var) as key and the variable's value as slice of string. For example, given the following INI file, [section1] key = value [section2 "sub"] key2 = value2 key2 = value3 it will be mapped as, map["section1..key"] = []string{"value"} map["section2.sub.key2"] = []string{"value2", "value3"} --- lib/ini/ini.go | 49 +++++++++++++++++++++++++++++++++++++++++++++ lib/ini/ini_example_test.go | 40 ++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 lib/ini/ini_example_test.go diff --git a/lib/ini/ini.go b/lib/ini/ini.go index 597b3b80..0b541e54 100644 --- a/lib/ini/ini.go +++ b/lib/ini/ini.go @@ -162,6 +162,55 @@ func Parse(text []byte) (in *Ini, err error) { return reader.Parse(text) } +// +// AsMap return the INI contents as mapping of +// (section-name ":" subsection-name ":" variable-name) as key +// and the variable's values as slice of string. +// For example, given the following INI file, +// +// [section1] +// key = value +// +// [section2 "sub"] +// key2 = value2 +// key2 = value3 +// +// it will be mapped as, +// +// map["section1::key"] = []string{"value"} +// map["section2:sub:key2"] = []string{"value2", "value3"} +// +func (in *Ini) AsMap() (out map[string][]string) { + sep := ":" + out = make(map[string][]string) + + for x := 0; x < len(in.secs); x++ { + sec := in.secs[x] + + for y := 0; y < len(sec.Vars); y++ { + v := sec.Vars[y] + + if v.mode == varModeEmpty { + continue + } + if v.mode&varModeSection > 0 || v.mode&varModeSubsection > 0 { + continue + } + + key := sec.NameLower + sep + sec.Sub + sep + v.KeyLower + + vals, ok := out[key] + if !ok { + out[key] = []string{v.Value} + } else { + out[key] = libstrings.AppendUniq(vals, v.Value) + } + } + } + + return +} + // // Save the current parsed Ini into file `filename`. It will overwrite the // destination file if it's exist. diff --git a/lib/ini/ini_example_test.go b/lib/ini/ini_example_test.go new file mode 100644 index 00000000..a2cb3d44 --- /dev/null +++ b/lib/ini/ini_example_test.go @@ -0,0 +1,40 @@ +package ini + +import ( + "fmt" + "log" +) + +func ExampleIni_AsMap() { + input := []byte(` +[section] +key=value1 +key2= + +[section "sub"] +key=value1 + +[section] +key=value2 +key2=false + +[section "sub"] +key=value2 +key=value3 +`) + + inis, err := Parse(input) + if err != nil { + log.Fatal(err) + } + + iniMap := inis.AsMap() + + for k, v := range iniMap { + fmt.Println(k, "=", v) + } + // Unordered output: + // section::key = [value1 value2] + // section::key2 = [true false] + // section:sub:key = [value1 value2 value3] +} -- cgit v1.3