Skip to content

Commit

Permalink
Merge pull request #16 from infrawatch/asimilatemap
Browse files Browse the repository at this point in the history
Move map operations from tools
  • Loading branch information
paramite authored Mar 25, 2021
2 parents 7d3567e + 917be5d commit 482adc4
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 0 deletions.
67 changes: 67 additions & 0 deletions misc/structs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package misc

import (
"fmt"
"log"
"strings"
)

// AssimilateMap recursively saves content of the given map to destination map of strings
func AssimilateMap(theMap map[string]interface{}, destination *map[string]string) {
defer func() { // recover from any panic
if r := recover(); r != nil {
log.Printf("Panic:recovered in assimilateMap %v\n", r)
}
}()
for key, val := range theMap {
switch value := val.(type) {
case map[string]interface{}:
// go one level deeper in the map
AssimilateMap(value, destination)
case []interface{}:
// transform slice value to comma separated list and assimilate it
aList := make([]string, 0, len(value))
for _, item := range value {
if itm, ok := item.(string); ok {
aList = append(aList, itm)
}
}
(*destination)[key] = strings.Join(aList, ",")
case float64, float32:
(*destination)[key] = fmt.Sprintf("%f", value)
case int, int8, int16, int32, int64:
(*destination)[key] = fmt.Sprintf("%d", value)
case bool:
(*destination)[key] = fmt.Sprintf("%t", value)
default:
// assimilate KV pair
if stringer, ok := value.(fmt.Stringer); ok {
(*destination)[key] = stringer.String()
} else {
(*destination)[key] = value.(string)
}
}
}
}

// MergeMaps merges given maps into a new one
func MergeMaps(ms ...map[string]interface{}) map[string]interface{} {
res := make(map[string]interface{})
for _, m := range ms {
for k, v := range m {
switch value := v.(type) {
case map[string]interface{}:
// go one level deeper in the map
res[k] = MergeMaps(value)
case []interface{}:
vCopy := make([]interface{}, len(value))
copy(vCopy, value)
res[k] = vCopy
default:
// assimilate KV pair
res[k] = value
}
}
}
return res
}
95 changes: 95 additions & 0 deletions tests/misc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package tests

import (
"fmt"
"testing"

"github.com/infrawatch/apputils/misc"
"github.com/stretchr/testify/assert"
)

type TestStringer struct {
numvalue int
strvalue string
}

func (ts TestStringer) String() string {
return fmt.Sprintf("%s %d!", ts.strvalue, ts.numvalue)
}

func TestStructsOperations(t *testing.T) {
map1 := map[string]interface{}{
"map": map[string]interface{}{
"a": "A",
"b": "B",
"c": map[string]interface{}{
"1": 1,
"2": 2,
},
"d": []interface{}{"d1", "d2"},
},
"slice": []interface{}{
"A",
"B",
},
"float32": float32(.32),
"float64": float64(.64),
"int": int(1),
"int8": int8(2),
"int16": int16(3),
"int32": int32(4),
"int64": int64(5),
"bool": true,
"string": "dub dub",
"stringer": TestStringer{numvalue: 666, strvalue: "wubba lubba"},
}
map2 := map[string]string{"key": "value"}
map3 := map[string]interface{}{
"map": map[string]interface{}{"foo": "bar"},
"slice": []interface{}{"wubba", "lubba", "dub dub"},
}

t.Run("Test AssimilateMap", func(t *testing.T) {
testAssimilate := map[string]string{
"key": "value",
"a": "A",
"b": "B",
"1": "1",
"2": "2",
"d": "d1,d2",
"slice": "A,B",
"float32": "0.320000",
"float64": "0.640000",
"int": "1",
"int8": "2",
"int16": "3",
"int32": "4",
"int64": "5",
"bool": "true",
"string": "dub dub",
"stringer": "wubba lubba 666!",
}
misc.AssimilateMap(map1, &map2)
assert.Equal(t, testAssimilate, map2)
})

t.Run("Test MergeMaps", func(t *testing.T) {
testMerge := map[string]interface{}{
"float32": float32(.32),
"float64": float64(.64),
"int": int(1),
"int8": int8(2),
"int16": int16(3),
"int32": int32(4),
"int64": int64(5),
"bool": true,
"string": "dub dub",
"stringer": TestStringer{numvalue: 666, strvalue: "wubba lubba"},
"map": map[string]interface{}{"foo": "bar"},
"slice": []interface{}{"wubba", "lubba", "dub dub"},
}
map4 := misc.MergeMaps(map1, map3)
assert.Equal(t, testMerge, map4)
})

}

0 comments on commit 482adc4

Please sign in to comment.