| package stdlib |
| |
| import ( |
| "fmt" |
| |
| "github.com/zclconf/go-cty/cty/convert" |
| |
| "github.com/zclconf/go-cty/cty" |
| "github.com/zclconf/go-cty/cty/function" |
| ) |
| |
| var SetHasElementFunc = function.New(&function.Spec{ |
| Params: []function.Parameter{ |
| { |
| Name: "set", |
| Type: cty.Set(cty.DynamicPseudoType), |
| AllowDynamicType: true, |
| }, |
| { |
| Name: "elem", |
| Type: cty.DynamicPseudoType, |
| AllowDynamicType: true, |
| }, |
| }, |
| Type: function.StaticReturnType(cty.Bool), |
| Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { |
| return args[0].HasElement(args[1]), nil |
| }, |
| }) |
| |
| var SetUnionFunc = function.New(&function.Spec{ |
| Params: []function.Parameter{ |
| { |
| Name: "first_set", |
| Type: cty.Set(cty.DynamicPseudoType), |
| AllowDynamicType: true, |
| }, |
| }, |
| VarParam: &function.Parameter{ |
| Name: "other_sets", |
| Type: cty.Set(cty.DynamicPseudoType), |
| AllowDynamicType: true, |
| }, |
| Type: setOperationReturnType, |
| Impl: setOperationImpl(func(s1, s2 cty.ValueSet) cty.ValueSet { |
| return s1.Union(s2) |
| }), |
| }) |
| |
| var SetIntersectionFunc = function.New(&function.Spec{ |
| Params: []function.Parameter{ |
| { |
| Name: "first_set", |
| Type: cty.Set(cty.DynamicPseudoType), |
| AllowDynamicType: true, |
| }, |
| }, |
| VarParam: &function.Parameter{ |
| Name: "other_sets", |
| Type: cty.Set(cty.DynamicPseudoType), |
| AllowDynamicType: true, |
| }, |
| Type: setOperationReturnType, |
| Impl: setOperationImpl(func(s1, s2 cty.ValueSet) cty.ValueSet { |
| return s1.Intersection(s2) |
| }), |
| }) |
| |
| var SetSubtractFunc = function.New(&function.Spec{ |
| Params: []function.Parameter{ |
| { |
| Name: "a", |
| Type: cty.Set(cty.DynamicPseudoType), |
| AllowDynamicType: true, |
| }, |
| { |
| Name: "b", |
| Type: cty.Set(cty.DynamicPseudoType), |
| AllowDynamicType: true, |
| }, |
| }, |
| Type: setOperationReturnType, |
| Impl: setOperationImpl(func(s1, s2 cty.ValueSet) cty.ValueSet { |
| return s1.Subtract(s2) |
| }), |
| }) |
| |
| var SetSymmetricDifferenceFunc = function.New(&function.Spec{ |
| Params: []function.Parameter{ |
| { |
| Name: "first_set", |
| Type: cty.Set(cty.DynamicPseudoType), |
| AllowDynamicType: true, |
| }, |
| }, |
| VarParam: &function.Parameter{ |
| Name: "other_sets", |
| Type: cty.Set(cty.DynamicPseudoType), |
| AllowDynamicType: true, |
| }, |
| Type: setOperationReturnType, |
| Impl: setOperationImpl(func(s1, s2 cty.ValueSet) cty.ValueSet { |
| return s1.Subtract(s2) |
| }), |
| }) |
| |
| // SetHasElement determines whether the given set contains the given value as an |
| // element. |
| func SetHasElement(set cty.Value, elem cty.Value) (cty.Value, error) { |
| return SetHasElementFunc.Call([]cty.Value{set, elem}) |
| } |
| |
| // SetUnion returns a new set containing all of the elements from the given |
| // sets, which must have element types that can all be converted to some |
| // common type using the standard type unification rules. If conversion |
| // is not possible, an error is returned. |
| // |
| // The union operation is performed after type conversion, which may result |
| // in some previously-distinct values being conflated. |
| // |
| // At least one set must be provided. |
| func SetUnion(sets ...cty.Value) (cty.Value, error) { |
| return SetUnionFunc.Call(sets) |
| } |
| |
| // Intersection returns a new set containing the elements that exist |
| // in all of the given sets, which must have element types that can all be |
| // converted to some common type using the standard type unification rules. |
| // If conversion is not possible, an error is returned. |
| // |
| // The intersection operation is performed after type conversion, which may |
| // result in some previously-distinct values being conflated. |
| // |
| // At least one set must be provided. |
| func SetIntersection(sets ...cty.Value) (cty.Value, error) { |
| return SetIntersectionFunc.Call(sets) |
| } |
| |
| // SetSubtract returns a new set containing the elements from the |
| // first set that are not present in the second set. The sets must have |
| // element types that can both be converted to some common type using the |
| // standard type unification rules. If conversion is not possible, an error |
| // is returned. |
| // |
| // The subtract operation is performed after type conversion, which may |
| // result in some previously-distinct values being conflated. |
| func SetSubtract(a, b cty.Value) (cty.Value, error) { |
| return SetSubtractFunc.Call([]cty.Value{a, b}) |
| } |
| |
| // SetSymmetricDifference returns a new set containing elements that appear |
| // in any of the given sets but not multiple. The sets must have |
| // element types that can all be converted to some common type using the |
| // standard type unification rules. If conversion is not possible, an error |
| // is returned. |
| // |
| // The difference operation is performed after type conversion, which may |
| // result in some previously-distinct values being conflated. |
| func SetSymmetricDifference(sets ...cty.Value) (cty.Value, error) { |
| return SetSymmetricDifferenceFunc.Call(sets) |
| } |
| |
| func setOperationReturnType(args []cty.Value) (ret cty.Type, err error) { |
| var etys []cty.Type |
| for _, arg := range args { |
| etys = append(etys, arg.Type().ElementType()) |
| } |
| newEty, _ := convert.UnifyUnsafe(etys) |
| if newEty == cty.NilType { |
| return cty.NilType, fmt.Errorf("given sets must all have compatible element types") |
| } |
| return cty.Set(newEty), nil |
| } |
| |
| func setOperationImpl(f func(s1, s2 cty.ValueSet) cty.ValueSet) function.ImplFunc { |
| return func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { |
| first := args[0] |
| first, err = convert.Convert(first, retType) |
| if err != nil { |
| return cty.NilVal, function.NewArgError(0, err) |
| } |
| |
| set := first.AsValueSet() |
| for i, arg := range args[1:] { |
| arg, err := convert.Convert(arg, retType) |
| if err != nil { |
| return cty.NilVal, function.NewArgError(i+1, err) |
| } |
| |
| argSet := arg.AsValueSet() |
| set = f(set, argSet) |
| } |
| return cty.SetValFromValueSet(set), nil |
| } |
| } |