diff --git a/tpl/template_funcs.go b/tpl/template_funcs.go index 8f5526378..4ed6a159f 100644 --- a/tpl/template_funcs.go +++ b/tpl/template_funcs.go @@ -239,6 +239,21 @@ func slicestr(a interface{}, startEnd ...interface{}) (string, error) { } +// hasPrefix tests whether the input s begins with prefix. +func hasPrefix(s, prefix interface{}) (bool, error) { + ss, err := cast.ToStringE(s) + if err != nil { + return false, err + } + + sp, err := cast.ToStringE(prefix) + if err != nil { + return false, err + } + + return strings.HasPrefix(ss, sp), nil +} + // substr extracts parts of a string, beginning at the character at the specified // position, and returns the specified number of characters. // @@ -2060,7 +2075,7 @@ func initFuncMap() { "getJSON": getJSON, "getenv": func(varName string) string { return os.Getenv(varName) }, "gt": gt, - "hasPrefix": func(a, b string) bool { return strings.HasPrefix(a, b) }, + "hasPrefix": hasPrefix, "highlight": highlight, "htmlEscape": htmlEscape, "htmlUnescape": htmlUnescape, diff --git a/tpl/template_funcs_test.go b/tpl/template_funcs_test.go index f94ec6a79..c5fb4c03d 100644 --- a/tpl/template_funcs_test.go +++ b/tpl/template_funcs_test.go @@ -804,6 +804,33 @@ func TestSlicestr(t *testing.T) { } } +func TestHasPrefix(t *testing.T) { + cases := []struct { + s interface{} + prefix interface{} + want interface{} + isErr bool + }{ + {"abcd", "ab", true, false}, + {"abcd", "cd", false, false}, + {template.HTML("abcd"), "ab", true, false}, + {template.HTML("abcd"), "cd", false, false}, + {template.HTML("1234"), 12, true, false}, + {template.HTML("1234"), 34, false, false}, + {[]byte("abcd"), "ab", true, false}, + } + + for i, c := range cases { + res, err := hasPrefix(c.s, c.prefix) + if (err != nil) != c.isErr { + t.Fatalf("[%d] unexpected isErr state: want %v, got %v, err = %v", i, c.isErr, err != nil, err) + } + if res != c.want { + t.Errorf("[%d] want %v, got %v", i, c.want, res) + } + } +} + func TestSubstr(t *testing.T) { var err error var n int