github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/terraform/flatten.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 "reflect" 6 ) 7 8 // remoteStateFlatten takes a structure and turns into a flat map[string]string. 9 // 10 // Within the "thing" parameter, only primitive values are allowed. Structs are 11 // not supported. Therefore, it can only be slices, maps, primitives, and 12 // any combination of those together. 13 // 14 // The difference between this version and the version in package flatmap is that 15 // we add the count key for maps in this version, and return a normal 16 // map[string]string instead of a flatmap.Map 17 func remoteStateFlatten(thing map[string]interface{}) map[string]string { 18 result := make(map[string]string) 19 20 for k, raw := range thing { 21 flatten(result, k, reflect.ValueOf(raw)) 22 } 23 24 return result 25 } 26 27 func flatten(result map[string]string, prefix string, v reflect.Value) { 28 if v.Kind() == reflect.Interface { 29 v = v.Elem() 30 } 31 32 switch v.Kind() { 33 case reflect.Bool: 34 if v.Bool() { 35 result[prefix] = "true" 36 } else { 37 result[prefix] = "false" 38 } 39 case reflect.Int: 40 result[prefix] = fmt.Sprintf("%d", v.Int()) 41 case reflect.Map: 42 flattenMap(result, prefix, v) 43 case reflect.Slice: 44 flattenSlice(result, prefix, v) 45 case reflect.String: 46 result[prefix] = v.String() 47 default: 48 panic(fmt.Sprintf("Unknown: %s", v)) 49 } 50 } 51 52 func flattenMap(result map[string]string, prefix string, v reflect.Value) { 53 mapKeys := v.MapKeys() 54 55 result[fmt.Sprintf("%s.%%", prefix)] = fmt.Sprintf("%d", len(mapKeys)) 56 for _, k := range mapKeys { 57 if k.Kind() == reflect.Interface { 58 k = k.Elem() 59 } 60 61 if k.Kind() != reflect.String { 62 panic(fmt.Sprintf("%s: map key is not string: %s", prefix, k)) 63 } 64 65 flatten(result, fmt.Sprintf("%s.%s", prefix, k.String()), v.MapIndex(k)) 66 } 67 } 68 69 func flattenSlice(result map[string]string, prefix string, v reflect.Value) { 70 prefix = prefix + "." 71 72 result[prefix+"#"] = fmt.Sprintf("%d", v.Len()) 73 for i := 0; i < v.Len(); i++ { 74 flatten(result, fmt.Sprintf("%s%d", prefix, i), v.Index(i)) 75 } 76 }