func filterKey(data map[interface{}]interface{}, key []string) (filtered, rest map[interface{}]interface{}) { if len(key) == 0 { return data, map[interface{}]interface{}{} } filtered = map[interface{}]interface{}{} rest = util.MapCopy(data) k := key[0] if d, ok := data[k]; ok { switch d := d.(type) { case map[interface{}]interface{}: f, r := filterKey(d, key[1:]) if len(f) != 0 { filtered[k] = f } if len(r) != 0 { rest[k] = r } else { delete(rest, k) } default: filtered[k] = d delete(rest, k) } } return }
func filterDottedKeys(data map[interface{}]interface{}, keys []string) (filtered, rest map[interface{}]interface{}) { filtered = map[interface{}]interface{}{} rest = util.MapCopy(data) for _, key := range keys { f, r := filterKey(data, strings.Split(key, ".")) filtered = util.MapsUnion(filtered, f) rest = util.MapsIntersection(rest, r) } return }
func TestMapsIntersection(t *testing.T) { assert := require.New(t) m0 := map[interface{}]interface{}{"a": 1, "b": map[interface{}]interface{}{"c": 3}, "d": "4"} m1 := util.MapCopy(m0) delete(m0, "a") b1 := m1["b"].(map[interface{}]interface{}) delete(b1, "c") expected := map[interface{}]interface{}{"b": map[interface{}]interface{}{}, "d": "4"} assert.Equal(expected, util.MapsIntersection(m0, m1, util.Equal)) }
func TestMapsUnion(t *testing.T) { assert := require.New(t) m0 := map[interface{}]interface{}{"a": 1, "b": map[interface{}]interface{}{"c": 3}, "d": "4"} m1 := util.MapCopy(m0) m1["e"] = "added" m1["d"] = "replaced" delete(m0, "a") b1 := m1["b"].(map[interface{}]interface{}) delete(b1, "c") expected := map[interface{}]interface{}{"a": 1, "b": map[interface{}]interface{}{"c": 3}, "d": "replaced", "e": "added"} assert.Equal(expected, util.MapsUnion(m0, m1, util.Replace)) }
func TestMapCopy(t *testing.T) { assert := require.New(t) m0 := map[interface{}]interface{}{"a": 1, "b": map[interface{}]interface{}{"c": 3}, "d": "4"} m1 := util.MapCopy(m0) delete(m0, "a") assert.Equal(len(m1), len(m0)+1) b0 := m0["b"].(map[interface{}]interface{}) b1 := m1["b"].(map[interface{}]interface{}) b1["e"] = "queer" assert.Equal(len(b1), len(b0)+1) }
func getOrSetVal(args string, data map[interface{}]interface{}, value interface{}) (interface{}, map[interface{}]interface{}) { parts := strings.Split(args, ".") tData := data if value != nil { tData = util.MapCopy(data) } t := tData for i, part := range parts { val, ok := t[part] last := i+1 == len(parts) // Reached end, set the value if last && value != nil { if s, ok := value.(string); ok { value = DummyMarshall(s) } t[part] = value return value, tData } // Missing intermediate key, create key if !last && value != nil && !ok { newData := map[interface{}]interface{}{} t[part] = newData t = newData continue } if !ok { break } if last { return val, tData } newData, ok := val.(map[interface{}]interface{}) if !ok { break } t = newData } return "", tData }
func addServices(p *project.Project, enabled map[interface{}]interface{}, configs map[string]*project.ServiceConfig) map[interface{}]interface{} { // Note: we ignore errors while loading services unchanged := true for name, serviceConfig := range configs { hash := project.GetServiceHash(name, *serviceConfig) if enabled[name] == hash { continue } if err := p.AddConfig(name, serviceConfig); err != nil { log.Infof("Failed loading service %s", name) continue } if unchanged { enabled = util.MapCopy(enabled) unchanged = false } enabled[name] = hash } return enabled }