// deepClone makes a deep clone of the given mapstr.M. It also replaces any // map[string]interface{} values with mapstr.M values. func deepClone(m mapstr.M) mapstr.M { return convertMapsToMapstr(m, true).(mapstr.M) } // convertMapsToMapstr replaces any map[string]interface{} values with // mapstr.M values. It converts maps found within map[string]interface{}, // mapstr.M, and []interface{} types. func convertMapsToMapstr(in interface{}, clone bool) interface{} { switch v := in.(type) { case map[string]interface{}: return convertMapValuesToMapstr(v, clone) case mapstr.M: return convertMapValuesToMapstr(v, clone) case []interface{}: return convertArrayValuesToMapstr(v, clone) default: return in } } // convertMapValuesToMapstr iterates through the map values and converts all // map[string]interface{} values to mapstr.M. func convertMapValuesToMapstr(in mapstr.M, clone bool) mapstr.M { out := in if clone { out = make(mapstr.M, len(in)) } for k, v := range in { out[k] = convertMapsToMapstr(v, clone) } return out } func convertArrayValuesToMapstr(in []interface{}, clone bool) []interface{} { out := in if clone { out = make([]interface{}, len(in)) } for i, item := range in { out[i] = convertMapsToMapstr(item, clone) } return out }