summaryrefslogtreecommitdiffstats
path: root/tpl
diff options
context:
space:
mode:
authorCameron Moore <moorereason@gmail.com>2016-03-09 14:40:00 -0600
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2016-03-10 17:47:59 +0100
commitce9ee3cf490ab5485b6ad7aa7a47d9fa9d176fa3 (patch)
treeb22524babedb88d1dca06ad2e9416d8a0fb03ee4 /tpl
parent0962470850ed6802b645d5bd6663db60807c8f5b (diff)
tpl: Add default function
Diffstat (limited to 'tpl')
-rw-r--r--tpl/template_funcs.go39
-rw-r--r--tpl/template_funcs_test.go45
2 files changed, 81 insertions, 3 deletions
diff --git a/tpl/template_funcs.go b/tpl/template_funcs.go
index 1cbc7d32b..8a0672726 100644
--- a/tpl/template_funcs.go
+++ b/tpl/template_funcs.go
@@ -1239,6 +1239,44 @@ func dateFormat(layout string, v interface{}) (string, error) {
return t.Format(layout), nil
}
+// dfault checks whether a given value is set and returns a default value if it
+// is not. "Set" in this context means true for booleans; non-zero for numeric
+// types; non-zero length for strings, arrays, slices, and maps; any struct
+// value; or non-nil for any other types.
+func dfault(dflt, given interface{}) interface{} {
+ g := reflect.ValueOf(given)
+ if !g.IsValid() {
+ return dflt
+ }
+
+ set := false
+
+ switch g.Kind() {
+ case reflect.Bool:
+ set = g.Bool()
+ case reflect.String, reflect.Array, reflect.Slice, reflect.Map:
+ set = g.Len() != 0
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ set = g.Int() != 0
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ set = g.Uint() != 0
+ case reflect.Float32, reflect.Float64:
+ set = g.Float() != 0
+ case reflect.Complex64, reflect.Complex128:
+ set = g.Complex() != 0
+ case reflect.Struct:
+ set = true
+ default:
+ set = !g.IsNil()
+ }
+
+ if set {
+ return given
+ }
+
+ return dflt
+}
+
// safeHTMLAttr returns a given string as html/template HTMLAttr content.
//
// safeHTMLAttr is currently disabled, pending further discussion
@@ -1537,6 +1575,7 @@ func init() {
"chomp": chomp,
"countrunes": countRunes,
"countwords": countWords,
+ "default": dfault,
"dateFormat": dateFormat,
"delimit": delimit,
"dict": dictionary,
diff --git a/tpl/template_funcs_test.go b/tpl/template_funcs_test.go
index 878b31d20..ae1161f27 100644
--- a/tpl/template_funcs_test.go
+++ b/tpl/template_funcs_test.go
@@ -18,9 +18,6 @@ import (
"encoding/base64"
"errors"
"fmt"
- "github.com/spf13/cast"
- "github.com/spf13/viper"
- "github.com/stretchr/testify/assert"
"html/template"
"math/rand"
"path"
@@ -29,6 +26,10 @@ import (
"strings"
"testing"
"time"
+
+ "github.com/spf13/cast"
+ "github.com/spf13/viper"
+ "github.com/stretchr/testify/assert"
)
type tstNoStringer struct {
@@ -1843,6 +1844,44 @@ func TestDateFormat(t *testing.T) {
}
}
+func TestDefault(t *testing.T) {
+ for i, this := range []struct {
+ dflt interface{}
+ given interface{}
+ expected interface{}
+ }{
+ {"5", 0, "5"},
+
+ {"test1", "set", "set"},
+ {"test2", "", "test2"},
+
+ {[2]int{10, 20}, [2]int{1, 2}, [2]int{1, 2}},
+ {[2]int{10, 20}, [0]int{}, [2]int{10, 20}},
+
+ {[]string{"one"}, []string{"uno"}, []string{"uno"}},
+ {[]string{"one"}, []string{}, []string{"one"}},
+
+ {map[string]int{"one": 1}, map[string]int{"uno": 1}, map[string]int{"uno": 1}},
+ {map[string]int{"one": 1}, map[string]int{}, map[string]int{"one": 1}},
+
+ {10, 1, 1},
+ {10, 0, 10},
+
+ {float32(10), float32(1), float32(1)},
+ {float32(10), 0, float32(10)},
+
+ {complex(2, -2), complex(1, -1), complex(1, -1)},
+ {complex(2, -2), complex(0, 0), complex(2, -2)},
+
+ {struct{ f string }{f: "one"}, struct{ f string }{}, struct{ f string }{}},
+ } {
+ res := dfault(this.dflt, this.given)
+ if !reflect.DeepEqual(this.expected, res) {
+ t.Errorf("[%d] default returned %v, but expected %v", i, res, this.expected)
+ }
+ }
+}
+
func TestSafeHTML(t *testing.T) {
for i, this := range []struct {
str string