From 591610deea0f3fcf6f97f11098eaae3e4aec4379 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 14 Jan 2015 12:02:26 -0800 Subject: [PATCH] config/lang: string to int --- config/lang/builtins.go | 18 ++++++++++++++++++ config/lang/engine.go | 3 +++ config/lang/engine_test.go | 19 +++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/config/lang/builtins.go b/config/lang/builtins.go index 7472389f09..edeee29f2e 100644 --- a/config/lang/builtins.go +++ b/config/lang/builtins.go @@ -6,11 +6,14 @@ import ( "github.com/hashicorp/terraform/config/lang/ast" ) +// NOTE: All builtins are tested in engine_test.go + func registerBuiltins(scope *Scope) { if scope.FuncMap == nil { scope.FuncMap = make(map[string]Function) } scope.FuncMap["__builtin_IntToString"] = builtinIntToString() + scope.FuncMap["__builtin_StringToInt"] = builtinStringToInt() } func builtinIntToString() Function { @@ -22,3 +25,18 @@ func builtinIntToString() Function { }, } } + +func builtinStringToInt() Function { + return Function{ + ArgTypes: []ast.Type{ast.TypeInt}, + ReturnType: ast.TypeString, + Callback: func(args []interface{}) (interface{}, error) { + v, err := strconv.ParseInt(args[0].(string), 0, 0) + if err != nil { + return nil, err + } + + return int(v), nil + }, + } +} diff --git a/config/lang/engine.go b/config/lang/engine.go index f54d6a9d3b..23d4ca6f79 100644 --- a/config/lang/engine.go +++ b/config/lang/engine.go @@ -33,6 +33,9 @@ func (e *Engine) Execute(root ast.Node) (interface{}, ast.Type, error) { ast.TypeInt: { ast.TypeString: "__builtin_IntToString", }, + ast.TypeString: { + ast.TypeInt: "__builtin_StringToInt", + }, } // Build our own semantic checks that we always run diff --git a/config/lang/engine_test.go b/config/lang/engine_test.go index 1a5a7b4c56..488d56be71 100644 --- a/config/lang/engine_test.go +++ b/config/lang/engine_test.go @@ -2,6 +2,7 @@ package lang import ( "reflect" + "strconv" "testing" "github.com/hashicorp/terraform/config/lang/ast" @@ -94,6 +95,24 @@ func TestEngineExecute(t *testing.T) { "foo 42", ast.TypeString, }, + + { + `foo ${foo("42")}`, + &Scope{ + FuncMap: map[string]Function{ + "foo": Function{ + ArgTypes: []ast.Type{ast.TypeInt}, + ReturnType: ast.TypeString, + Callback: func(args []interface{}) (interface{}, error) { + return strconv.FormatInt(int64(args[0].(int)), 10), nil + }, + }, + }, + }, + false, + "foo 42", + ast.TypeString, + }, } for _, tc := range cases {