Merge pull request #9692 from jszwedko/add-basic-math-interpolation
Add some basic math interpolation functions
This commit is contained in:
commit
0d921cf8e7
|
@ -10,6 +10,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -54,6 +55,7 @@ func Funcs() map[string]ast.Function {
|
||||||
"base64decode": interpolationFuncBase64Decode(),
|
"base64decode": interpolationFuncBase64Decode(),
|
||||||
"base64encode": interpolationFuncBase64Encode(),
|
"base64encode": interpolationFuncBase64Encode(),
|
||||||
"base64sha256": interpolationFuncBase64Sha256(),
|
"base64sha256": interpolationFuncBase64Sha256(),
|
||||||
|
"ceil": interpolationFuncCeil(),
|
||||||
"cidrhost": interpolationFuncCidrHost(),
|
"cidrhost": interpolationFuncCidrHost(),
|
||||||
"cidrnetmask": interpolationFuncCidrNetmask(),
|
"cidrnetmask": interpolationFuncCidrNetmask(),
|
||||||
"cidrsubnet": interpolationFuncCidrSubnet(),
|
"cidrsubnet": interpolationFuncCidrSubnet(),
|
||||||
|
@ -63,6 +65,7 @@ func Funcs() map[string]ast.Function {
|
||||||
"distinct": interpolationFuncDistinct(),
|
"distinct": interpolationFuncDistinct(),
|
||||||
"element": interpolationFuncElement(),
|
"element": interpolationFuncElement(),
|
||||||
"file": interpolationFuncFile(),
|
"file": interpolationFuncFile(),
|
||||||
|
"floor": interpolationFuncFloor(),
|
||||||
"format": interpolationFuncFormat(),
|
"format": interpolationFuncFormat(),
|
||||||
"formatlist": interpolationFuncFormatList(),
|
"formatlist": interpolationFuncFormatList(),
|
||||||
"index": interpolationFuncIndex(),
|
"index": interpolationFuncIndex(),
|
||||||
|
@ -72,8 +75,10 @@ func Funcs() map[string]ast.Function {
|
||||||
"list": interpolationFuncList(),
|
"list": interpolationFuncList(),
|
||||||
"lower": interpolationFuncLower(),
|
"lower": interpolationFuncLower(),
|
||||||
"map": interpolationFuncMap(),
|
"map": interpolationFuncMap(),
|
||||||
|
"max": interpolationFuncMax(),
|
||||||
"md5": interpolationFuncMd5(),
|
"md5": interpolationFuncMd5(),
|
||||||
"merge": interpolationFuncMerge(),
|
"merge": interpolationFuncMerge(),
|
||||||
|
"min": interpolationFuncMin(),
|
||||||
"uuid": interpolationFuncUUID(),
|
"uuid": interpolationFuncUUID(),
|
||||||
"replace": interpolationFuncReplace(),
|
"replace": interpolationFuncReplace(),
|
||||||
"sha1": interpolationFuncSha1(),
|
"sha1": interpolationFuncSha1(),
|
||||||
|
@ -387,6 +392,66 @@ func interpolationFuncFormat() ast.Function {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// interpolationFuncMax returns the maximum of the numeric arguments
|
||||||
|
func interpolationFuncMax() ast.Function {
|
||||||
|
return ast.Function{
|
||||||
|
ArgTypes: []ast.Type{ast.TypeFloat},
|
||||||
|
ReturnType: ast.TypeFloat,
|
||||||
|
Variadic: true,
|
||||||
|
VariadicType: ast.TypeFloat,
|
||||||
|
Callback: func(args []interface{}) (interface{}, error) {
|
||||||
|
max := args[0].(float64)
|
||||||
|
|
||||||
|
for i := 1; i < len(args); i++ {
|
||||||
|
max = math.Max(max, args[i].(float64))
|
||||||
|
}
|
||||||
|
|
||||||
|
return max, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// interpolationFuncMin returns the minimum of the numeric arguments
|
||||||
|
func interpolationFuncMin() ast.Function {
|
||||||
|
return ast.Function{
|
||||||
|
ArgTypes: []ast.Type{ast.TypeFloat},
|
||||||
|
ReturnType: ast.TypeFloat,
|
||||||
|
Variadic: true,
|
||||||
|
VariadicType: ast.TypeFloat,
|
||||||
|
Callback: func(args []interface{}) (interface{}, error) {
|
||||||
|
min := args[0].(float64)
|
||||||
|
|
||||||
|
for i := 1; i < len(args); i++ {
|
||||||
|
min = math.Min(min, args[i].(float64))
|
||||||
|
}
|
||||||
|
|
||||||
|
return min, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// interpolationFuncCeil returns the the least integer value greater than or equal to the argument
|
||||||
|
func interpolationFuncCeil() ast.Function {
|
||||||
|
return ast.Function{
|
||||||
|
ArgTypes: []ast.Type{ast.TypeFloat},
|
||||||
|
ReturnType: ast.TypeInt,
|
||||||
|
Callback: func(args []interface{}) (interface{}, error) {
|
||||||
|
return int(math.Ceil(args[0].(float64))), nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// interpolationFuncFloorreturns returns the greatest integer value less than or equal to the argument
|
||||||
|
func interpolationFuncFloor() ast.Function {
|
||||||
|
return ast.Function{
|
||||||
|
ArgTypes: []ast.Type{ast.TypeFloat},
|
||||||
|
ReturnType: ast.TypeInt,
|
||||||
|
Callback: func(args []interface{}) (interface{}, error) {
|
||||||
|
return int(math.Floor(args[0].(float64))), nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func interpolationFuncZipMap() ast.Function {
|
func interpolationFuncZipMap() ast.Function {
|
||||||
return ast.Function{
|
return ast.Function{
|
||||||
ArgTypes: []ast.Type{
|
ArgTypes: []ast.Type{
|
||||||
|
|
|
@ -222,6 +222,150 @@ func TestInterpolateFuncList(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInterpolateFuncMax(t *testing.T) {
|
||||||
|
testFunction(t, testFunctionConfig{
|
||||||
|
Cases: []testFunctionCase{
|
||||||
|
{
|
||||||
|
`${max()}`,
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${max("")}`,
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${max(-1, 0, 1)}`,
|
||||||
|
"1",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${max(1, 0, -1)}`,
|
||||||
|
"1",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${max(-1, -2)}`,
|
||||||
|
"-1",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${max(-1)}`,
|
||||||
|
"-1",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInterpolateFuncMin(t *testing.T) {
|
||||||
|
testFunction(t, testFunctionConfig{
|
||||||
|
Cases: []testFunctionCase{
|
||||||
|
{
|
||||||
|
`${min()}`,
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${min("")}`,
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${min(-1, 0, 1)}`,
|
||||||
|
"-1",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${min(1, 0, -1)}`,
|
||||||
|
"-1",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${min(-1, -2)}`,
|
||||||
|
"-2",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${min(-1)}`,
|
||||||
|
"-1",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInterpolateFuncFloor(t *testing.T) {
|
||||||
|
testFunction(t, testFunctionConfig{
|
||||||
|
Cases: []testFunctionCase{
|
||||||
|
{
|
||||||
|
`${floor()}`,
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${floor("")}`,
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${floor("-1.3")}`, // there appears to be a AST bug where the parsed argument ends up being -1 without the "s
|
||||||
|
"-2",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${floor(1.7)}`,
|
||||||
|
"1",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInterpolateFuncCeil(t *testing.T) {
|
||||||
|
testFunction(t, testFunctionConfig{
|
||||||
|
Cases: []testFunctionCase{
|
||||||
|
{
|
||||||
|
`${ceil()}`,
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${ceil("")}`,
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${ceil(-1.8)}`,
|
||||||
|
"-1",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
`${ceil(1.2)}`,
|
||||||
|
"2",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestInterpolateFuncMap(t *testing.T) {
|
func TestInterpolateFuncMap(t *testing.T) {
|
||||||
testFunction(t, testFunctionConfig{
|
testFunction(t, testFunctionConfig{
|
||||||
Cases: []testFunctionCase{
|
Cases: []testFunctionCase{
|
||||||
|
|
|
@ -89,6 +89,9 @@ The supported built-in functions are:
|
||||||
**This is not equivalent** of `base64encode(sha256(string))`
|
**This is not equivalent** of `base64encode(sha256(string))`
|
||||||
since `sha256()` returns hexadecimal representation.
|
since `sha256()` returns hexadecimal representation.
|
||||||
|
|
||||||
|
* `ceil(float)` - Returns the the least integer value greater than or equal
|
||||||
|
to the argument.
|
||||||
|
|
||||||
* `cidrhost(iprange, hostnum)` - Takes an IP address range in CIDR notation
|
* `cidrhost(iprange, hostnum)` - Takes an IP address range in CIDR notation
|
||||||
and creates an IP address with the given host number. For example,
|
and creates an IP address with the given host number. For example,
|
||||||
``cidrhost("10.0.0.0/8", 2)`` returns ``10.0.0.2``.
|
``cidrhost("10.0.0.0/8", 2)`` returns ``10.0.0.2``.
|
||||||
|
@ -137,6 +140,9 @@ The supported built-in functions are:
|
||||||
module, you generally want to make the path relative to the module base,
|
module, you generally want to make the path relative to the module base,
|
||||||
like this: `file("${path.module}/file")`.
|
like this: `file("${path.module}/file")`.
|
||||||
|
|
||||||
|
* `floor(float)` - Returns the greatest integer value less than or equal to
|
||||||
|
the argument
|
||||||
|
|
||||||
* `format(format, args, ...)` - Formats a string according to the given
|
* `format(format, args, ...)` - Formats a string according to the given
|
||||||
format. The syntax for the format is standard `sprintf` syntax.
|
format. The syntax for the format is standard `sprintf` syntax.
|
||||||
Good documentation for the syntax can be [found here](https://golang.org/pkg/fmt/).
|
Good documentation for the syntax can be [found here](https://golang.org/pkg/fmt/).
|
||||||
|
@ -197,11 +203,15 @@ The supported built-in functions are:
|
||||||
* `map("hello", "world")`
|
* `map("hello", "world")`
|
||||||
* `map("us-east", list("a", "b", "c"), "us-west", list("b", "c", "d"))`
|
* `map("us-east", list("a", "b", "c"), "us-west", list("b", "c", "d"))`
|
||||||
|
|
||||||
|
* `max(float1, float2, ...)` - Returns the largest of the floats.
|
||||||
|
|
||||||
* `merge(map1, map2, ...)` - Returns the union of 2 or more maps. The maps
|
* `merge(map1, map2, ...)` - Returns the union of 2 or more maps. The maps
|
||||||
are consumed in the order provided, and duplicate keys overwrite previous
|
are consumed in the order provided, and duplicate keys overwrite previous
|
||||||
entries.
|
entries.
|
||||||
* `${merge(map("a", "b"), map("c", "d"))}` returns `{"a": "b", "c": "d"}`
|
* `${merge(map("a", "b"), map("c", "d"))}` returns `{"a": "b", "c": "d"}`
|
||||||
|
|
||||||
|
* `min(float1, float2, ...)` - Returns the smallest of the floats.
|
||||||
|
|
||||||
* `md5(string)` - Returns a (conventional) hexadecimal representation of the
|
* `md5(string)` - Returns a (conventional) hexadecimal representation of the
|
||||||
MD5 hash of the given string.
|
MD5 hash of the given string.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue