mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-23 11:44:26 -05:00
112 lines
3.5 KiB
Go
112 lines
3.5 KiB
Go
package structured
|
|
|
|
import (
|
|
"github.com/hashicorp/terraform/internal/command/jsonformat/structured/attribute_path"
|
|
)
|
|
|
|
// ChangeMap is a Change that represents a Map or an Object type, and has
|
|
// converted the relevant interfaces into maps for easier access.
|
|
type ChangeMap struct {
|
|
// Before contains the value before the proposed change.
|
|
Before map[string]interface{}
|
|
|
|
// After contains the value after the proposed change.
|
|
After map[string]interface{}
|
|
|
|
// Unknown contains the unknown status of any elements/attributes of this
|
|
// map/object.
|
|
Unknown map[string]interface{}
|
|
|
|
// BeforeSensitive contains the before sensitive status of any
|
|
// elements/attributes of this map/object.
|
|
BeforeSensitive map[string]interface{}
|
|
|
|
// AfterSensitive contains the after sensitive status of any
|
|
// elements/attributes of this map/object.
|
|
AfterSensitive map[string]interface{}
|
|
|
|
// ReplacePaths matches the same attributes in Change exactly.
|
|
ReplacePaths attribute_path.Matcher
|
|
|
|
// RelevantAttributes matches the same attributes in Change exactly.
|
|
RelevantAttributes attribute_path.Matcher
|
|
}
|
|
|
|
// AsMap converts the Change into an object or map representation by converting
|
|
// the internal Before, After, Unknown, BeforeSensitive, and AfterSensitive
|
|
// data structures into generic maps.
|
|
func (change Change) AsMap() ChangeMap {
|
|
return ChangeMap{
|
|
Before: genericToMap(change.Before),
|
|
After: genericToMap(change.After),
|
|
Unknown: genericToMap(change.Unknown),
|
|
BeforeSensitive: genericToMap(change.BeforeSensitive),
|
|
AfterSensitive: genericToMap(change.AfterSensitive),
|
|
ReplacePaths: change.ReplacePaths,
|
|
RelevantAttributes: change.RelevantAttributes,
|
|
}
|
|
}
|
|
|
|
// GetChild safely packages up a Change object for the given child, handling
|
|
// all the cases where the data might be null or a static boolean.
|
|
func (m ChangeMap) GetChild(key string) Change {
|
|
before, beforeExplicit := getFromGenericMap(m.Before, key)
|
|
after, afterExplicit := getFromGenericMap(m.After, key)
|
|
unknown, _ := getFromGenericMap(m.Unknown, key)
|
|
beforeSensitive, _ := getFromGenericMap(m.BeforeSensitive, key)
|
|
afterSensitive, _ := getFromGenericMap(m.AfterSensitive, key)
|
|
|
|
return Change{
|
|
BeforeExplicit: beforeExplicit,
|
|
AfterExplicit: afterExplicit,
|
|
Before: before,
|
|
After: after,
|
|
Unknown: unknown,
|
|
BeforeSensitive: beforeSensitive,
|
|
AfterSensitive: afterSensitive,
|
|
ReplacePaths: m.ReplacePaths.GetChildWithKey(key),
|
|
RelevantAttributes: m.RelevantAttributes.GetChildWithKey(key),
|
|
}
|
|
}
|
|
|
|
// Keys returns all the possible keys for this map. The keys for the map are
|
|
// potentially hidden and spread across multiple internal data structures and
|
|
// so this function conveniently packages them up.
|
|
func (m ChangeMap) Keys() []string {
|
|
var keys []string
|
|
for before := range m.Before {
|
|
keys = append(keys, before)
|
|
}
|
|
for after := range m.After {
|
|
keys = append(keys, after)
|
|
}
|
|
for unknown := range m.Unknown {
|
|
keys = append(keys, unknown)
|
|
}
|
|
for sensitive := range m.AfterSensitive {
|
|
keys = append(keys, sensitive)
|
|
}
|
|
for sensitive := range m.BeforeSensitive {
|
|
keys = append(keys, sensitive)
|
|
}
|
|
return keys
|
|
}
|
|
|
|
func getFromGenericMap(generic map[string]interface{}, key string) (interface{}, bool) {
|
|
if generic == nil {
|
|
return nil, false
|
|
}
|
|
|
|
if child, ok := generic[key]; ok {
|
|
return child, ok
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
func genericToMap(generic interface{}) map[string]interface{} {
|
|
if concrete, ok := generic.(map[string]interface{}); ok {
|
|
return concrete
|
|
}
|
|
return nil
|
|
}
|