Add a function to find the index of an element in a list.

This commit is contained in:
Jason Gedge 2015-07-12 15:55:19 -04:00 committed by Jason Gedge
parent 7f738dc272
commit cf5926ddad
3 changed files with 56 additions and 0 deletions

View File

@ -24,6 +24,7 @@ func init() {
"file": interpolationFuncFile(), "file": interpolationFuncFile(),
"format": interpolationFuncFormat(), "format": interpolationFuncFormat(),
"formatlist": interpolationFuncFormatList(), "formatlist": interpolationFuncFormatList(),
"index": interpolationFuncIndex(),
"join": interpolationFuncJoin(), "join": interpolationFuncJoin(),
"length": interpolationFuncLength(), "length": interpolationFuncLength(),
"replace": interpolationFuncReplace(), "replace": interpolationFuncReplace(),
@ -178,6 +179,25 @@ func interpolationFuncFormatList() ast.Function {
} }
} }
// interpolationFuncIndex implements the "index" function that allows one to
// find the index of a specific element in a list
func interpolationFuncIndex() ast.Function {
return ast.Function{
ArgTypes: []ast.Type{ast.TypeString, ast.TypeString},
ReturnType: ast.TypeInt,
Callback: func(args []interface{}) (interface{}, error) {
haystack := StringList(args[0].(string)).Slice()
needle := args[1].(string)
for index, element := range haystack {
if needle == element {
return index, nil
}
}
return nil, fmt.Errorf("Could not find '%s' in '%s'", needle, haystack)
},
}
}
// interpolationFuncJoin implements the "join" function that allows // interpolationFuncJoin implements the "join" function that allows
// multi-variable values to be joined by some character. // multi-variable values to be joined by some character.
func interpolationFuncJoin() ast.Function { func interpolationFuncJoin() ast.Function {

View File

@ -206,6 +206,39 @@ func TestInterpolateFuncFormatList(t *testing.T) {
}) })
} }
func TestInterpolateFuncIndex(t *testing.T) {
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
{
`${index("test", "")}`,
nil,
true,
},
{
fmt.Sprintf(`${index("%s", "foo")}`,
NewStringList([]string{"notfoo", "stillnotfoo", "bar"}).String()),
nil,
true,
},
{
fmt.Sprintf(`${index("%s", "foo")}`,
NewStringList([]string{"foo"}).String()),
"0",
false,
},
{
fmt.Sprintf(`${index("%s", "bar")}`,
NewStringList([]string{"foo", "spam", "bar", "eggs"}).String()),
"2",
false,
},
},
})
}
func TestInterpolateFuncJoin(t *testing.T) { func TestInterpolateFuncJoin(t *testing.T) {
testFunction(t, testFunctionConfig{ testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{ Cases: []testFunctionCase{

View File

@ -102,6 +102,9 @@ The supported built-in functions are:
`formatlist("instance %v has private ip %v", aws_instance.foo.*.id, aws_instance.foo.*.private_ip)`. `formatlist("instance %v has private ip %v", aws_instance.foo.*.id, aws_instance.foo.*.private_ip)`.
Passing lists with different lengths to formatlist results in an error. Passing lists with different lengths to formatlist results in an error.
* `index(list, elem)` - Finds the index of a given element in a list. Example:
`index(aws_instance.foo.*.tags.Name, "foo-test")`
* `join(delim, list)` - Joins the list with the delimiter. A list is * `join(delim, list)` - Joins the list with the delimiter. A list is
only possible with splat variables from resources with a count only possible with splat variables from resources with a count
greater than one. Example: `join(",", aws_instance.foo.*.id)` greater than one. Example: `join(",", aws_instance.foo.*.id)`