]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blobdiff - vendor/github.com/zclconf/go-cty/cty/convert/conversion_collection.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / zclconf / go-cty / cty / convert / conversion_collection.go
index eace85d3dd37fe7b426f220ba727cde7133c6d89..3039ba22e54507e1e1c51972e8df1b803e9fc9f4 100644 (file)
@@ -84,6 +84,120 @@ func conversionCollectionToSet(ety cty.Type, conv conversion) conversion {
        }
 }
 
+// conversionCollectionToMap returns a conversion that will apply the given
+// conversion to all of the elements of a collection (something that supports
+// ForEachElement and LengthInt) and then returns the result as a map.
+//
+// "conv" can be nil if the elements are expected to already be of the
+// correct type and just need to be re-wrapped into a map.
+func conversionCollectionToMap(ety cty.Type, conv conversion) conversion {
+       return func(val cty.Value, path cty.Path) (cty.Value, error) {
+               elems := make(map[string]cty.Value, 0)
+               path = append(path, nil)
+               it := val.ElementIterator()
+               for it.Next() {
+                       key, val := it.Element()
+                       var err error
+
+                       path[len(path)-1] = cty.IndexStep{
+                               Key: key,
+                       }
+
+                       keyStr, err := Convert(key, cty.String)
+                       if err != nil {
+                               // Should never happen, because keys can only be numbers or
+                               // strings and both can convert to string.
+                               return cty.DynamicVal, path.NewErrorf("cannot convert key type %s to string for map", key.Type().FriendlyName())
+                       }
+
+                       if conv != nil {
+                               val, err = conv(val, path)
+                               if err != nil {
+                                       return cty.NilVal, err
+                               }
+                       }
+
+                       elems[keyStr.AsString()] = val
+               }
+
+               if len(elems) == 0 {
+                       return cty.MapValEmpty(ety), nil
+               }
+
+               return cty.MapVal(elems), nil
+       }
+}
+
+// conversionTupleToSet returns a conversion that will take a value of the
+// given tuple type and return a set of the given element type.
+//
+// Will panic if the given tupleType isn't actually a tuple type.
+func conversionTupleToSet(tupleType cty.Type, listEty cty.Type, unsafe bool) conversion {
+       tupleEtys := tupleType.TupleElementTypes()
+
+       if len(tupleEtys) == 0 {
+               // Empty tuple short-circuit
+               return func(val cty.Value, path cty.Path) (cty.Value, error) {
+                       return cty.SetValEmpty(listEty), nil
+               }
+       }
+
+       if listEty == cty.DynamicPseudoType {
+               // This is a special case where the caller wants us to find
+               // a suitable single type that all elements can convert to, if
+               // possible.
+               listEty, _ = unify(tupleEtys, unsafe)
+               if listEty == cty.NilType {
+                       return nil
+               }
+       }
+
+       elemConvs := make([]conversion, len(tupleEtys))
+       for i, tupleEty := range tupleEtys {
+               if tupleEty.Equals(listEty) {
+                       // no conversion required
+                       continue
+               }
+
+               elemConvs[i] = getConversion(tupleEty, listEty, unsafe)
+               if elemConvs[i] == nil {
+                       // If any of our element conversions are impossible, then the our
+                       // whole conversion is impossible.
+                       return nil
+               }
+       }
+
+       // If we fall out here then a conversion is possible, using the
+       // element conversions in elemConvs
+       return func(val cty.Value, path cty.Path) (cty.Value, error) {
+               elems := make([]cty.Value, 0, len(elemConvs))
+               path = append(path, nil)
+               i := int64(0)
+               it := val.ElementIterator()
+               for it.Next() {
+                       _, val := it.Element()
+                       var err error
+
+                       path[len(path)-1] = cty.IndexStep{
+                               Key: cty.NumberIntVal(i),
+                       }
+
+                       conv := elemConvs[i]
+                       if conv != nil {
+                               val, err = conv(val, path)
+                               if err != nil {
+                                       return cty.NilVal, err
+                               }
+                       }
+                       elems = append(elems, val)
+
+                       i++
+               }
+
+               return cty.SetVal(elems), nil
+       }
+}
+
 // conversionTupleToList returns a conversion that will take a value of the
 // given tuple type and return a list of the given element type.
 //