opentofu/builtin/providers/terraform/flatten.go
Martin Atkins a3ced1a367 provider/terraform: reorganize for merge into core
The "terraform" provider was previously split out into its own repository,
but that turned out to be a mistake due to how tightly it depends on
aspects of Terraform Core.

Here we prepare to bring it back into the core repository by reorganizing
the directory layout to conform with what's expected there.
2017-11-02 10:46:31 -07:00

77 lines
1.9 KiB
Go

package terraform
import (
"fmt"
"reflect"
)
// remoteStateFlatten takes a structure and turns into a flat map[string]string.
//
// Within the "thing" parameter, only primitive values are allowed. Structs are
// not supported. Therefore, it can only be slices, maps, primitives, and
// any combination of those together.
//
// The difference between this version and the version in package flatmap is that
// we add the count key for maps in this version, and return a normal
// map[string]string instead of a flatmap.Map
func remoteStateFlatten(thing map[string]interface{}) map[string]string {
result := make(map[string]string)
for k, raw := range thing {
flatten(result, k, reflect.ValueOf(raw))
}
return result
}
func flatten(result map[string]string, prefix string, v reflect.Value) {
if v.Kind() == reflect.Interface {
v = v.Elem()
}
switch v.Kind() {
case reflect.Bool:
if v.Bool() {
result[prefix] = "true"
} else {
result[prefix] = "false"
}
case reflect.Int:
result[prefix] = fmt.Sprintf("%d", v.Int())
case reflect.Map:
flattenMap(result, prefix, v)
case reflect.Slice:
flattenSlice(result, prefix, v)
case reflect.String:
result[prefix] = v.String()
default:
panic(fmt.Sprintf("Unknown: %s", v))
}
}
func flattenMap(result map[string]string, prefix string, v reflect.Value) {
mapKeys := v.MapKeys()
result[fmt.Sprintf("%s.%%", prefix)] = fmt.Sprintf("%d", len(mapKeys))
for _, k := range mapKeys {
if k.Kind() == reflect.Interface {
k = k.Elem()
}
if k.Kind() != reflect.String {
panic(fmt.Sprintf("%s: map key is not string: %s", prefix, k))
}
flatten(result, fmt.Sprintf("%s.%s", prefix, k.String()), v.MapIndex(k))
}
}
func flattenSlice(result map[string]string, prefix string, v reflect.Value) {
prefix = prefix + "."
result[prefix+"#"] = fmt.Sprintf("%d", v.Len())
for i := 0; i < v.Len(); i++ {
flatten(result, fmt.Sprintf("%s%d", prefix, i), v.Index(i))
}
}