aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/zclconf/go-cty/cty/convert/conversion_object.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/zclconf/go-cty/cty/convert/conversion_object.go')
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/convert/conversion_object.go76
1 files changed, 76 insertions, 0 deletions
diff --git a/vendor/github.com/zclconf/go-cty/cty/convert/conversion_object.go b/vendor/github.com/zclconf/go-cty/cty/convert/conversion_object.go
new file mode 100644
index 0000000..62dabb8
--- /dev/null
+++ b/vendor/github.com/zclconf/go-cty/cty/convert/conversion_object.go
@@ -0,0 +1,76 @@
1package convert
2
3import (
4 "github.com/zclconf/go-cty/cty"
5)
6
7// conversionObjectToObject returns a conversion that will make the input
8// object type conform to the output object type, if possible.
9//
10// Conversion is possible only if the output type is a subset of the input
11// type, meaning that each attribute of the output type has a corresponding
12// attribute in the input type where a recursive conversion is available.
13//
14// Shallow object conversions work the same for both safe and unsafe modes,
15// but the safety flag is passed on to recursive conversions and may thus
16// limit the above definition of "subset".
17func conversionObjectToObject(in, out cty.Type, unsafe bool) conversion {
18 inAtys := in.AttributeTypes()
19 outAtys := out.AttributeTypes()
20 attrConvs := make(map[string]conversion)
21
22 for name, outAty := range outAtys {
23 inAty, exists := inAtys[name]
24 if !exists {
25 // No conversion is available, then.
26 return nil
27 }
28
29 if inAty.Equals(outAty) {
30 // No conversion needed, but we'll still record the attribute
31 // in our map for later reference.
32 attrConvs[name] = nil
33 continue
34 }
35
36 attrConvs[name] = getConversion(inAty, outAty, unsafe)
37 if attrConvs[name] == nil {
38 // If a recursive conversion isn't available, then our top-level
39 // configuration is impossible too.
40 return nil
41 }
42 }
43
44 // If we get here then a conversion is possible, using the attribute
45 // conversions given in attrConvs.
46 return func(val cty.Value, path cty.Path) (cty.Value, error) {
47 attrVals := make(map[string]cty.Value, len(attrConvs))
48 path = append(path, nil)
49 pathStep := &path[len(path)-1]
50
51 for it := val.ElementIterator(); it.Next(); {
52 nameVal, val := it.Element()
53 var err error
54
55 name := nameVal.AsString()
56 *pathStep = cty.GetAttrStep{
57 Name: name,
58 }
59
60 conv, exists := attrConvs[name]
61 if !exists {
62 continue
63 }
64 if conv != nil {
65 val, err = conv(val, path)
66 if err != nil {
67 return cty.NilVal, err
68 }
69 }
70
71 attrVals[name] = val
72 }
73
74 return cty.ObjectVal(attrVals), nil
75 }
76}