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 } }