Files
opentf/internal/command/jsonformat/differ/value_map.go
Liam Cervante aff94591c1 Add support for lists in the structured renderer (#32401)
* prep for processing the structured run output

* undo unwanted change to a json key

* Add skeleton functions and API for refactored renderer

* goimports

* Fix documentation of the RenderOpts struct

* Add rendering functionality for primitives to the structured renderer

* add test case for override

* Add support for parsing and rendering sensitive values in the renderer

* Add support for unknown/computed values in the structured renderer

* delete missing unit tests

* Add support for object attributes in the structured renderer

* goimports

* Add support for the replace paths data in the structured renderer

* Add support for maps in the structured renderer

* Add support for lists in the structured renderer

* goimports

* add additional comments explaining
2023-01-09 14:06:38 +01:00

94 lines
2.6 KiB
Go

package differ
// ValueMap is a Value that represents a Map or an Object type, and has
// converted the relevant interfaces into maps for easier access.
type ValueMap 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 Value exactly.
ReplacePaths []interface{}
}
func (v Value) asMap() ValueMap {
return ValueMap{
Before: genericToMap(v.Before),
After: genericToMap(v.After),
Unknown: genericToMap(v.Unknown),
BeforeSensitive: genericToMap(v.BeforeSensitive),
AfterSensitive: genericToMap(v.AfterSensitive),
ReplacePaths: v.ReplacePaths,
}
}
func (m ValueMap) getChild(key string) Value {
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 Value{
BeforeExplicit: beforeExplicit,
AfterExplicit: afterExplicit,
Before: before,
After: after,
Unknown: unknown,
BeforeSensitive: beforeSensitive,
AfterSensitive: afterSensitive,
ReplacePaths: m.processReplacePaths(key),
}
}
func (m ValueMap) processReplacePaths(key string) []interface{} {
var ret []interface{}
for _, p := range m.ReplacePaths {
path := p.([]interface{})
if len(path) == 0 {
// This means that the current value is causing a replacement but
// not its children, so we skip as we are returning the child's
// value.
continue
}
if path[0].(string) == key {
ret = append(ret, path[1:])
}
}
return ret
}
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
}