github.com/hashicorp/packer@v1.14.3/hcl2template/function/index.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package function 5 6 import ( 7 "errors" 8 9 "github.com/zclconf/go-cty/cty" 10 "github.com/zclconf/go-cty/cty/function" 11 "github.com/zclconf/go-cty/cty/function/stdlib" 12 ) 13 14 // IndexFunc constructs a function that finds the element index for a given value in a list. 15 var IndexFunc = function.New(&function.Spec{ 16 Params: []function.Parameter{ 17 { 18 Name: "list", 19 Type: cty.DynamicPseudoType, 20 }, 21 { 22 Name: "value", 23 Type: cty.DynamicPseudoType, 24 }, 25 }, 26 Type: function.StaticReturnType(cty.Number), 27 RefineResult: refineNotNull, 28 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { 29 if !(args[0].Type().IsListType() || args[0].Type().IsTupleType()) { 30 return cty.NilVal, errors.New("argument must be a list or tuple") 31 } 32 33 if !args[0].IsKnown() { 34 return cty.UnknownVal(cty.Number), nil 35 } 36 37 if args[0].LengthInt() == 0 { // Easy path 38 return cty.NilVal, errors.New("cannot search an empty list") 39 } 40 41 for it := args[0].ElementIterator(); it.Next(); { 42 i, v := it.Element() 43 eq, err := stdlib.Equal(v, args[1]) 44 if err != nil { 45 return cty.NilVal, err 46 } 47 if !eq.IsKnown() { 48 return cty.UnknownVal(cty.Number), nil 49 } 50 if eq.True() { 51 return i, nil 52 } 53 } 54 return cty.NilVal, errors.New("item not found") 55 56 }, 57 }) 58 59 // Index finds the element index for a given value in a list. 60 func Index(list, value cty.Value) (cty.Value, error) { 61 return IndexFunc.Call([]cty.Value{list, value}) 62 }