Skip to content

Commit

Permalink
Add length function
Browse files Browse the repository at this point in the history
  • Loading branch information
cam-stitt committed Dec 4, 2017
1 parent 5373ae1 commit e706b0e
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 1 deletion.
3 changes: 2 additions & 1 deletion examples/input.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
"i": ${i},
"j": "${join(", ", h)}",
"other": "${upper("foobar")}",
"foo": "${join(" | ", list("foo", "bar"))}"
"foo": "${join(" | ", list("foo", "bar"))}",
"len": ${length(h)}
}
25 changes: 25 additions & 0 deletions interpolation/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package interpolation

import (
"errors"
"fmt"
"os"

"github.com/hashicorp/hil/ast"
Expand All @@ -23,6 +24,7 @@ var CoreFunctions = map[string]ast.Function{
"min": interpolationFuncMin(),
"contains": interpolationFuncContains(),
"split": interpolationFuncSplit(),
"length": interpolationFuncLength(),
}

// interpolationFuncEnv will extract a variable out of the env
Expand All @@ -40,3 +42,26 @@ func interpolationFuncEnv() ast.Function {
},
}
}

// interpolationFuncLength will determine the length of the input
// if the input is a list, it will count the length of the items
// if the input is a map, it will count the keys
// if the input is a string, it will count the characters
func interpolationFuncLength() ast.Function {
return ast.Function{
ArgTypes: []ast.Type{ast.TypeAny},
ReturnType: ast.TypeInt,
Callback: func(inputs []interface{}) (interface{}, error) {
switch input := inputs[0].(type) {
case string:
return len(input), nil
case []ast.Variable:
return len(input), nil
case map[string]ast.Variable:
return len(input), nil
default:
return nil, fmt.Errorf("Must provide either a list, map or string, got %T", input)
}
},
}
}
37 changes: 37 additions & 0 deletions interpolation/funcs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,40 @@ func TestInterpolationFuncEnv(t *testing.T) {
})
}
}

func TestInterpolationFuncLength(t *testing.T) {
testCases := []functionTestCase{
{
description: "Length of string",
text: `${length("FOO")}`,
expectation: "3",
},
{
description: "Length of list",
text: `${length("${list("foo", "bar")}")}`,
expectation: "2",
},
{
description: "Length of map",
text: `${length("${map("foo", "bar")}")}`,
expectation: "1",
},
{
description: "Invalid type errors",
text: `${length(4)}`,
evalError: true,
},
}

lengthTestFunc := testInterpolationFunc(keyFuncs{
"length": interpolationFuncLength,
"list": interpolationFuncList,
"map": interpolationFuncMap,
})

for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
lengthTestFunc(t, tc)
})
}
}

0 comments on commit e706b0e

Please sign in to comment.