aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/zclconf/go-cty/cty/convert/conversion_tuple.go
blob: 592980a7012d0033e9fbe75cd1e9812ee3409637 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package convert

import (
	"github.com/zclconf/go-cty/cty"
)

// conversionTupleToTuple returns a conversion that will make the input
// tuple type conform to the output tuple type, if possible.
//
// Conversion is possible only if the two tuple types have the same number
// of elements and the corresponding elements by index can be converted.
//
// Shallow tuple conversions work the same for both safe and unsafe modes,
// but the safety flag is passed on to recursive conversions and may thus
// limit which element type conversions are possible.
func conversionTupleToTuple(in, out cty.Type, unsafe bool) conversion {
	inEtys := in.TupleElementTypes()
	outEtys := out.TupleElementTypes()

	if len(inEtys) != len(outEtys) {
		return nil // no conversion is possible
	}

	elemConvs := make([]conversion, len(inEtys))

	for i, outEty := range outEtys {
		inEty := inEtys[i]

		if inEty.Equals(outEty) {
			// No conversion needed, so we can leave this one nil.
			continue
		}

		elemConvs[i] = getConversion(inEty, outEty, unsafe)
		if elemConvs[i] == nil {
			// If a recursive conversion isn't available, then our top-level
			// configuration is impossible too.
			return nil
		}
	}

	// If we get here then a conversion is possible, using the element
	// conversions given in elemConvs.
	return func(val cty.Value, path cty.Path) (cty.Value, error) {
		elemVals := make([]cty.Value, len(elemConvs))
		path = append(path, nil)
		pathStep := &path[len(path)-1]

		i := 0
		for it := val.ElementIterator(); it.Next(); i++ {
			_, val := it.Element()
			var err error

			*pathStep = cty.IndexStep{
				Key: cty.NumberIntVal(int64(i)),
			}

			conv := elemConvs[i]
			if conv != nil {
				val, err = conv(val, path)
				if err != nil {
					return cty.NilVal, err
				}
			}

			elemVals[i] = val
		}

		return cty.TupleVal(elemVals), nil
	}
}