func (mapDec *mapDecoder) decode(node RMNode, data interface{}, v reflect.Value) { values, err := redis.Values(node.Value(), nil) if err != nil { panic(err) } size := len(values) / 2 vals, err := redis.Values(node.Value(), nil) if err != nil { panic(err) } v.Set(reflect.MakeMap(v.Type())) for i := 0; i < size; i++ { mKey, err := redis.String(values[i*2], nil) if err != nil { panic(err) } elemV := newValueForType(v.Type().Elem()) if i < node.Size() { mapDec.elemFunc(node.Child(i), vals[i*2+1], elemV) } else { mapDec.elemFunc(node, vals[i*2+1], elemV) } v.SetMapIndex(reflect.ValueOf(mKey), elemV) } }
func (d *decoder) mapCopy(src reflect.Value, dst reflect.Value) error { sv := src.MapKeys() dt := dst.Type().Elem() for i := range sv { ot := reflect.New(dt) if dt.Kind() == reflect.Ptr { ot = reflect.New(ot.Type().Elem()) } d.pushPath(sv[i].String()) err := d.decode(src.MapIndex(sv[i]), ot) if err != nil && err != ErrIncompatStruct { err = errors.New(d.pathString() + err.Error()) d.path = nil return err } d.popPath() if err == nil { dst.SetMapIndex(sv[i], ot.Elem()) } } return nil }
func decodeMap(d *decodeState, kind int, v reflect.Value) { t := v.Type() if t.Key().Kind() != reflect.String || kind != kindDocument { d.saveErrorAndSkip(kind, t) return } if v.IsNil() { v.Set(reflect.MakeMap(t)) } subv := reflect.New(t.Elem()).Elem() offset := d.beginDoc() for { kind, name := d.scanKindName() if kind == 0 { break } if kind == kindNull { continue } subv.Set(reflect.Zero(t.Elem())) d.decodeValue(kind, subv) v.SetMapIndex(reflect.ValueOf(string(name)), subv) } d.endDoc(offset) }
func (d *mapAsMapDecoder) decode(dv, sv reflect.Value) { dt := dv.Type() dv.Set(reflect.MakeMap(reflect.MapOf(dt.Key(), dt.Elem()))) var mapKey reflect.Value var mapElem reflect.Value keyType := dv.Type().Key() elemType := dv.Type().Elem() for _, sElemKey := range sv.MapKeys() { var dElemKey reflect.Value var dElemVal reflect.Value if !mapKey.IsValid() { mapKey = reflect.New(keyType).Elem() } else { mapKey.Set(reflect.Zero(keyType)) } dElemKey = mapKey if !mapElem.IsValid() { mapElem = reflect.New(elemType).Elem() } else { mapElem.Set(reflect.Zero(elemType)) } dElemVal = mapElem d.keyDec(dElemKey, sElemKey) d.elemDec(dElemVal, sv.MapIndex(sElemKey)) dv.SetMapIndex(dElemKey, dElemVal) } }
func (f *decFnInfo) kMap(rv reflect.Value) { containerLen := f.dd.readMapLen() if rv.IsNil() { rv.Set(reflect.MakeMap(f.rt)) } if containerLen == 0 { return } ktype, vtype := f.rt.Key(), f.rt.Elem() for j := 0; j < containerLen; j++ { rvk := reflect.New(ktype).Elem() f.d.decodeValue(rvk) if ktype == intfTyp { rvk = rvk.Elem() if rvk.Type() == byteSliceTyp { rvk = reflect.ValueOf(string(rvk.Bytes())) } } rvv := rv.MapIndex(rvk) if !rvv.IsValid() { rvv = reflect.New(vtype).Elem() } f.d.decodeValue(rvv) rv.SetMapIndex(rvk, rvv) } }
func deepCopyMap(src, dst reflect.Value, t reflect.Type) { for _, key := range src.MapKeys() { var nkey, nval reflect.Value if key.IsValid() && key.CanSet() { if key.Kind() == reflect.Ptr { nkey = reflect.New(key.Elem().Type()) } else { nkey = reflect.New(key.Type()) nkey = reflect.Indirect(nkey) } s := reflect.Indirect(key) d := reflect.Indirect(nkey) tt := s.Type() deepCopy(s, d, tt) } else { nkey = key } if val := src.MapIndex(key); val.IsValid() && val.CanSet() { if val.Kind() == reflect.Ptr { nval = reflect.New(val.Elem().Type()) } else { nval = reflect.New(val.Type()) nval = reflect.Indirect(nval) } s := reflect.Indirect(val) d := reflect.Indirect(nval) tt := s.Type() deepCopy(s, d, tt) } else { nval = val } dst.SetMapIndex(nkey, nval) } }
func Uniq(source, selector interface{}) interface{} { if selector == nil { selector = func(value, _ interface{}) Facade { return Facade{reflect.ValueOf(value)} } } var mapRV reflect.Value var arrRV reflect.Value each(source, selector, func(resRV, valueRv, _ reflect.Value) bool { if !mapRV.IsValid() { mapRT := reflect.MapOf(resRV.Type(), reflect.TypeOf(false)) mapRV = reflect.MakeMap(mapRT) arrRT := reflect.SliceOf(valueRv.Type()) arrRV = reflect.MakeSlice(arrRT, 0, 0) } mapValueRV := mapRV.MapIndex(resRV) if !mapValueRV.IsValid() { mapRV.SetMapIndex(resRV, reflect.ValueOf(true)) arrRV = reflect.Append(arrRV, valueRv) } return false }) if mapRV.IsValid() { return arrRV.Interface() } return nil }
func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error { tmap, ok := mapping.(map[string]interface{}) if !ok { if tmap == nil { return nil } return badtype("map", mapping) } if rv.IsNil() { rv.Set(reflect.MakeMap(rv.Type())) } for k, v := range tmap { md.decoded[md.context.add(k).String()] = true md.context = append(md.context, k) rvkey := indirect(reflect.New(rv.Type().Key())) rvval := reflect.Indirect(reflect.New(rv.Type().Elem())) if err := md.unify(v, rvval); err != nil { return err } md.context = md.context[0 : len(md.context)-1] rvkey.SetString(k) rv.SetMapIndex(rvkey, rvval) } return nil }
// MakeMap examines the key type from a Hash and create a map with builtin type if possible. // The idea is to avoid generating map[interface{}]interface{}, which cannot be handled by json.Marshal. func (h *Hash) MakeMap(pair map[interface{}]interface{}) interface{} { if !h.KeyType.Type.IsPrimitive() { // well, a type can't be handled by json.Marshal... not much we can do return pair } if len(pair) == 0 { // figure out the map type manually switch h.KeyType.Type.Kind() { case BooleanKind: return map[bool]interface{}{} case IntegerKind: return map[int]interface{}{} case NumberKind: return map[float64]interface{}{} case StringKind: return map[string]interface{}{} case DateTimeKind: return map[time.Time]interface{}{} default: return pair } } var newMap reflect.Value for key, value := range pair { rkey, rvalue := reflect.ValueOf(key), reflect.ValueOf(value) if !newMap.IsValid() { newMap = reflect.MakeMap(reflect.MapOf(rkey.Type(), rvalue.Type())) } newMap.SetMapIndex(rkey, rvalue) } return newMap.Interface() }
func (t *MapType) DeleteByPath(v *reflect.Value, path Path) (err error) { err = t.Init() if err != nil { return } if len(path) > 1 { vk, err := t.KeyStringConverter.FromString(path[0]) if err != nil { return err } ev := v.MapIndex(vk) et := t.ElemType oEv := ev err = et.DeleteByPath(&ev, path[1:]) if err != nil { return err } if oEv == ev { return nil } v.SetMapIndex(vk, ev) return nil } else if len(path) == 0 { return fmt.Errorf("[MapType.DeleteByPath] delete map with no path.") } //Addressable? vk, err := t.KeyStringConverter.FromString(path[0]) if err != nil { return err } v.SetMapIndex(vk, reflect.Value{}) return nil }
func (q *queryDecoder) decodeMap(output reflect.Value, prefix string, tag reflect.StructTag) error { // check for unflattened list member if !q.isEC2 && tag.Get("flattened") == "" { prefix += ".entry" } namer := newMapNamer(prefix, tag) mapType := output.Type() output.Set(reflect.MakeMap(mapType)) keyType := mapType.Key() valueType := mapType.Elem() for i := 0; ; i++ { keyName := namer.KeyName(i) if !q.containsPrefix(keyName) { break } key, err := q.getValue(keyName, keyType) if err != nil { return err } val, err := q.getValue(namer.ValueName(i), valueType) if err != nil { return err } output.SetMapIndex(key, val) } return nil }
func ensureMapKey(head P, mid string, obj, key reflect.Value, ctx *Context) (value reflect.Value, err error) { value = obj.MapIndex(key) if value.Kind() != reflect.Invalid { if !ctx.CreateIfMissing { return } if !isNillable(value) || !value.IsNil() { return } } if !ctx.CreateIfMissing { err = ErrMissing return } if value, err = zero(head, mid, obj.Type().Elem()); err != nil { return } obj.SetMapIndex(key, value) return }
func parseMap(key, keytail string, values []string, target reflect.Value) { t := target.Type() mapkey, maptail := keyed(t, key, keytail) // BUG(carl): We don't support any map keys except strings, although // there's no reason we shouldn't be able to throw the value through our // unparsing stack. var mk reflect.Value if t.Key().Kind() == reflect.String { mk = reflect.ValueOf(mapkey).Convert(t.Key()) } else { pebkac("key for map %v isn't a string (it's a %v).", t, t.Key()) } if target.IsNil() { target.Set(reflect.MakeMap(t)) } val := target.MapIndex(mk) if !val.IsValid() || !val.CanSet() { // It's a teensy bit annoying that the value returned by // MapIndex isn't Set()table if the key exists. val = reflect.New(t.Elem()).Elem() } parse(key, maptail, values, val) target.SetMapIndex(mk, val) }
// rcopy performs a recursive copy of values from the source to destination. // // root is used to skip certain aspects of the copy which are not valid // for the root node of a object. func rcopy(dst, src reflect.Value, root bool) { if !src.IsValid() { return } switch src.Kind() { case reflect.Ptr: if _, ok := src.Interface().(io.Reader); ok { if dst.Kind() == reflect.Ptr && dst.Elem().CanSet() { dst.Elem().Set(src) } else if dst.CanSet() { dst.Set(src) } } else { e := src.Type().Elem() if dst.CanSet() && !src.IsNil() { dst.Set(reflect.New(e)) } if src.Elem().IsValid() { // Keep the current root state since the depth hasn't changed rcopy(dst.Elem(), src.Elem(), root) } } case reflect.Struct: if !root { dst.Set(reflect.New(src.Type()).Elem()) } t := dst.Type() for i := 0; i < t.NumField(); i++ { name := t.Field(i).Name srcval := src.FieldByName(name) if srcval.IsValid() { rcopy(dst.FieldByName(name), srcval, false) } } case reflect.Slice: s := reflect.MakeSlice(src.Type(), src.Len(), src.Cap()) dst.Set(s) for i := 0; i < src.Len(); i++ { rcopy(dst.Index(i), src.Index(i), false) } case reflect.Map: s := reflect.MakeMap(src.Type()) dst.Set(s) for _, k := range src.MapKeys() { v := src.MapIndex(k) v2 := reflect.New(v.Type()).Elem() rcopy(v2, v, false) dst.SetMapIndex(k, v2) } default: // Assign the value if possible. If its not assignable, the value would // need to be converted and the impact of that may be unexpected, or is // not compatible with the dst type. if src.Type().AssignableTo(dst.Type()) { dst.Set(src) } } }
func (p *Decoder) unmarshalDictionary(pval *plistValue, val reflect.Value) { typ := val.Type() switch val.Kind() { case reflect.Struct: tinfo, err := getTypeInfo(typ) if err != nil { panic(err) } subvalues := pval.value.(*dictionary).m for _, finfo := range tinfo.fields { p.unmarshal(subvalues[finfo.name], finfo.value(val)) } case reflect.Map: if val.IsNil() { val.Set(reflect.MakeMap(typ)) } subvalues := pval.value.(*dictionary).m for k, sval := range subvalues { keyv := reflect.ValueOf(k).Convert(typ.Key()) mapElem := val.MapIndex(keyv) if !mapElem.IsValid() { mapElem = reflect.New(typ.Elem()).Elem() } p.unmarshal(sval, mapElem) val.SetMapIndex(keyv, mapElem) } default: panic(&incompatibleDecodeTypeError{typ, pval.kind}) } }
// unmarshalMap transforms the map node to a map represented by field. // This returns an error if the node cannot be converted to a map type func unmarshalMap(node yaml.Node, field reflect.Value, supportedYamlTags map[string]bool) error { mapNode, err := nodeToMap(node) if err != nil { return err } fieldType := field.Type() keyType := fieldType.Key() elemType := fieldType.Elem() // go-gypsy yaml has Map structure as map[string]Node, cannot process any other key type if keyType.Kind() != reflect.String { return fmt.Errorf("Unable to unmarshal map [%v]. Only string key type is supported.", field) } if field.IsNil() { field.Set(reflect.MakeMap(fieldType)) } for keyNode, valueNode := range mapNode { k := reflect.New(keyType).Elem() k.SetString(keyNode) e := reflect.New(elemType).Elem() if err := setValue(valueNode, elemType, e, supportedYamlTags); err != nil { return err } field.SetMapIndex(k, e) } return nil }
func decodeMap(v reflect.Value, x interface{}) { t := v.Type() if v.IsNil() { v.Set(reflect.MakeMap(t)) } for k, c := range getNode(x) { i := reflect.New(t.Key()).Elem() decodeValue(i, k) w := v.MapIndex(i) if w.IsValid() { // We have an actual element value to decode into. if w.Kind() == reflect.Interface { w = w.Elem() } w = reflect.New(w.Type()).Elem() } else if t.Elem().Kind() != reflect.Interface { // The map's element type is concrete. w = reflect.New(t.Elem()).Elem() } else { // The best we can do here is to decode as either a string (for scalars) or a map[string]interface {} (for the rest). // We could try to guess the type based on the string (e.g. true/false => bool) but that'll get ugly fast, // especially if we have to guess the kind (slice vs. array vs. map) and index type (e.g. string, int, etc.) switch c.(type) { case node: w = reflect.MakeMap(stringMapType) case string: w = reflect.New(stringType).Elem() default: panic("value is neither node nor string") } } decodeValue(w, c) v.SetMapIndex(i, w) } }
// decodeMap treats the next bytes as an XDR encoded variable array of 2-element // structures whose fields are of the same type as the map keys and elements // represented by the passed reflection value. Pointers are automatically // indirected and allocated as necessary. It returns the the number of bytes // actually read. // // An UnmarshalError is returned if any issues are encountered while decoding // the elements. func (d *Decoder) decodeMap(v reflect.Value) (int, error) { dataLen, n, err := d.DecodeUint() if err != nil { return n, err } // Allocate storage for the underlying map if needed. vt := v.Type() if v.IsNil() { v.Set(reflect.MakeMap(vt)) } // Decode each key and value according to their type. keyType := vt.Key() elemType := vt.Elem() for i := uint32(0); i < dataLen; i++ { key := reflect.New(keyType).Elem() n2, err := d.decode(key) n += n2 if err != nil { return n, err } val := reflect.New(elemType).Elem() n2, err = d.decode(val) n += n2 if err != nil { return n, err } v.SetMapIndex(key, val) } return n, nil }
func unmarshalMap(data string, v reflect.Value) error { mapType := v.Type() if mapType.Key().Kind() != reflect.String { return errors.New("tnetstring: only maps with string keys can be unmarshaled") } if v.IsNil() { v.Set(reflect.MakeMap(mapType)) } vtype := mapType.Elem() var s string key := reflect.ValueOf(&s).Elem() for len(data) > 0 { val := reflect.New(vtype).Elem() typ, content, n := readElement(data) data = data[n:] if typ != ',' { return errors.New("tnetstring: non-string key in dictionary") } s = content n, err := unmarshal(data, val) data = data[n:] if err != nil { return err } v.SetMapIndex(key, val) } return nil }
func reifyMap(opts *options, to reflect.Value, from *Config) Error { if to.Type().Key().Kind() != reflect.String { return raiseKeyInvalidTypeUnpack(to.Type(), from) } if len(from.fields.fields) == 0 { return nil } if to.IsNil() { to.Set(reflect.MakeMap(to.Type())) } for k, value := range from.fields.fields { key := reflect.ValueOf(k) old := to.MapIndex(key) var v reflect.Value var err Error if !old.IsValid() { v, err = reifyValue(fieldOptions{opts: opts}, to.Type().Elem(), value) } else { v, err = reifyMergeValue(fieldOptions{opts: opts}, old, value) } if err != nil { return err } to.SetMapIndex(key, v) } return nil }
func (d *Decoder) mapValue(v reflect.Value) error { n, err := d.DecodeMapLen() if err != nil { return err } if n == -1 { return nil } typ := v.Type() if v.IsNil() { v.Set(reflect.MakeMap(typ)) } keyType := typ.Key() valueType := typ.Elem() for i := 0; i < n; i++ { mk := reflect.New(keyType).Elem() if err := d.DecodeValue(mk); err != nil { return err } mv := reflect.New(valueType).Elem() if err := d.DecodeValue(mv); err != nil { return err } v.SetMapIndex(mk, mv) } return nil }
func unmarshalMap(value reflect.Value, data interface{}, tag reflect.StructTag) error { if data == nil { return nil } mapData, ok := data.(map[string]interface{}) if !ok { return fmt.Errorf("JSON value is not a map (%#v)", data) } t := value.Type() if value.Kind() == reflect.Ptr { t = t.Elem() if value.IsNil() { value.Set(reflect.New(t)) value.Elem().Set(reflect.MakeMap(t)) } value = value.Elem() } for k, v := range mapData { kvalue := reflect.ValueOf(k) vvalue := reflect.New(value.Type().Elem()).Elem() unmarshalAny(vvalue, v, "") value.SetMapIndex(kvalue, vvalue) } return nil }
func (d *decoder) mapping(n *node, out reflect.Value) (good bool) { if set := d.setter("!!map", &out, &good); set != nil { defer set() } if out.Kind() == reflect.Struct { return d.mappingStruct(n, out) } if out.Kind() == reflect.Interface { // No type hints. Will have to use a generic map. iface := out out = settableValueOf(make(map[interface{}]interface{})) iface.Set(out) } if out.Kind() != reflect.Map { return false } outt := out.Type() kt := outt.Key() et := outt.Elem() l := len(n.children) for i := 0; i < l; i += 2 { k := reflect.New(kt).Elem() if d.unmarshal(n.children[i], k) { e := reflect.New(et).Elem() if d.unmarshal(n.children[i+1], e) { out.SetMapIndex(k, e) } } } return true }
func (d *Decoder) mapping(v reflect.Value) { u, pv := d.indirect(v) if u != nil { defer func() { if err := u.UnmarshalYAML("!!map", pv.Interface()); err != nil { d.error(err) } }() _, pv = d.indirect(pv) } v = pv // Decoding into nil interface? Switch to non-reflect code. if v.Kind() == reflect.Interface && v.NumMethod() == 0 { v.Set(reflect.ValueOf(d.mappingInterface())) return } // Check type of target: struct or map[X]Y switch v.Kind() { case reflect.Struct: d.mappingStruct(v) return case reflect.Map: default: d.error(errors.New("mapping: invalid type: " + v.Type().String())) } mapt := v.Type() if v.IsNil() { v.Set(reflect.MakeMap(mapt)) } d.nextEvent() keyt := mapt.Key() mapElemt := mapt.Elem() var mapElem reflect.Value for { if d.event.event_type == yaml_MAPPING_END_EVENT { break } key := reflect.New(keyt) d.parse(key.Elem()) if !mapElem.IsValid() { mapElem = reflect.New(mapElemt).Elem() } else { mapElem.Set(reflect.Zero(mapElemt)) } d.parse(mapElem) v.SetMapIndex(key.Elem(), mapElem) } d.nextEvent() }
func MapBuilder(typ reflect.Type, map_ reflect.Value, key reflect.Value) *valueBuilder { if typ.Kind() == reflect.Ptr { addr := reflect.New(typ.Elem()) map_.SetMapIndex(key, addr) return &valueBuilder{val: addr.Elem()} } return &valueBuilder{val: reflect.New(typ).Elem(), map_: map_, key: key} }
func setMap(destVal reflect.Value, k interface{}, v LuaValue, destType reflect.Type) error { dest := reflect.New(destType.Elem()) if err := convertTableVal(v, dest.Interface()); err != nil { return err } destVal.SetMapIndex(reflect.ValueOf(k), dest.Elem()) return nil }
func (d *Decoder) readObjectField(v reflect.Value, key string) (ignored bool, err error) { if !v.CanSet() { panic("readObjectField: v must be settable") } var field reflect.Value switch v.Kind() { case reflect.Map: if v.IsNil() { v.Set(reflect.MakeMap(v.Type())) } elemType := v.Type().Elem() if elemType.Kind() == reflect.Ptr { field = reflect.New(elemType.Elem()) } else { field = reflect.New(elemType) } default: field = findFieldByName(v, key) if !field.IsValid() { var tmpobj interface{} field = reflect.ValueOf(&tmpobj).Elem() d.logPrintln("Prepared dummy value for non-exist key", key) ignored = true } if !field.CanSet() { d.logPrintln("v.Type()", v.Type()) d.logPrintln("field.Type():", field.Type()) panic("field not settable") } d.logPrintln("Original field type", field.Type()) if field.Kind() == reflect.Ptr { if field.IsNil() { if err = createReflectObject(field, field.Type().Elem()); err != nil { return } } } else { field = field.Addr() } } err = d.ReadValue(field.Interface()) d.logPrintln("Read field key", key, "type", field.Type(), "value", field.Elem().Interface()) if v.Kind() == reflect.Map { if v.Type().Elem().Kind() != reflect.Ptr { field = field.Elem() } v.SetMapIndex(reflect.ValueOf(key), field) } return }
// Reset a map, clearing all of its values func resetMap(out reflect.Value) { // Go over all of the Map keys for _, k := range out.MapKeys() { // Delete the all of the values out.SetMapIndex(k, zeroValue) } }
// copyRecursive does the actual copying of the interface. It currently has // limited support for what it can handle. Add as needed. func copyRecursive(original, cpy reflect.Value) { // handle according to original's Kind switch original.Kind() { case reflect.Ptr: // Get the actual value being pointed to. originalValue := original.Elem() // if it isn't valid, return. if !originalValue.IsValid() { return } cpy.Set(reflect.New(originalValue.Type())) copyRecursive(originalValue, cpy.Elem()) case reflect.Interface: // Get the value for the interface, not the pointer. originalValue := original.Elem() if !originalValue.IsValid() { return } // Get the value by calling Elem(). copyValue := reflect.New(originalValue.Type()).Elem() copyRecursive(originalValue, copyValue) cpy.Set(copyValue) case reflect.Struct: // Go through each field of the struct and copy it. for i := 0; i < original.NumField(); i++ { if cpy.Field(i).CanSet() { copyRecursive(original.Field(i), cpy.Field(i)) } } case reflect.Slice: // Make a new slice and copy each element. cpy.Set(reflect.MakeSlice(original.Type(), original.Len(), original.Cap())) for i := 0; i < original.Len(); i++ { copyRecursive(original.Index(i), cpy.Index(i)) } case reflect.Map: cpy.Set(reflect.MakeMap(original.Type())) for _, key := range original.MapKeys() { originalValue := original.MapIndex(key) copyValue := reflect.New(originalValue.Type()).Elem() copyRecursive(originalValue, copyValue) cpy.SetMapIndex(key, copyValue) } // Set the actual values from here on. case reflect.String: cpy.SetString(original.Interface().(string)) case reflect.Int: cpy.SetInt(int64(original.Interface().(int))) case reflect.Bool: cpy.SetBool(original.Interface().(bool)) case reflect.Float64: cpy.SetFloat(original.Interface().(float64)) default: cpy.Set(original) } }
// Traverses recursively both values, assigning src's fields values to dst. // The map argument tracks comparisons that have already been seen, which allows // short circuiting on recursive types. func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int) error { if !src.IsValid() { return nil } if dst.CanAddr() { addr := dst.UnsafeAddr() h := 17 * addr seen := visited[h] typ := dst.Type() for p := seen; p != nil; p = p.next { if p.ptr == addr && p.typ == typ { return nil } } // Remember, remember... visited[h] = &visit{addr, typ, seen} } switch dst.Kind() { case reflect.Struct: for i, n := 0, dst.NumField(); i < n; i++ { if err := deepMerge(dst.Field(i), src.Field(i), visited, depth+1); err != nil { return err } } case reflect.Map: for _, key := range src.MapKeys() { srcElement := src.MapIndex(key) if !srcElement.IsValid() { continue } dstElement := dst.MapIndex(key) switch reflect.TypeOf(srcElement.Interface()).Kind() { case reflect.Struct: fallthrough case reflect.Map: if err := deepMerge(dstElement, srcElement, visited, depth+1); err != nil { return err } default: dst.SetMapIndex(key, srcElement) } if !dstElement.IsValid() { dst.SetMapIndex(key, srcElement) } } case reflect.Interface: if err := deepMerge(dst.Elem(), src.Elem(), visited, depth+1); err != nil { return err } default: if dst.CanSet() && isEmptyValue(dst) { dst.Set(src) } } return nil }