ref: 7674ad73825c61eecc4003475fe0577f225fe579
parent: 08f48b91d68d3002b887ddf737456ff0cc4e786d
	author: Cameron Moore <moorereason@gmail.com>
	date: Thu Aug 17 22:12:04 EDT 2017
	
tpl: Add strings.TrimLeft and TrimRight
--- a/tpl/strings/init.go
+++ b/tpl/strings/init.go
@@ -112,6 +112,20 @@
},
)
+ ns.AddMethodMapping(ctx.TrimLeft,
+ nil,
+			[][2]string{+				{`{{ "aabbaa" | strings.TrimLeft "a" }}`, `bbaa`},+ },
+ )
+
+ ns.AddMethodMapping(ctx.TrimRight,
+ nil,
+			[][2]string{+				{`{{ "aabbaa" | strings.TrimRight "a" }}`, `aabb`},+ },
+ )
+
ns.AddMethodMapping(ctx.Title,
 			[]string{"title"}, 			[][2]string{--- a/tpl/strings/strings.go
+++ b/tpl/strings/strings.go
@@ -347,6 +347,22 @@
return _strings.Trim(ss, sc), nil
}
+// TrimLeft returns a slice of the string s with all leading characters
+// contained in cutset removed.
+func (ns *Namespace) TrimLeft(cutset, s interface{}) (string, error) {+ ss, err := cast.ToStringE(s)
+	if err != nil {+ return "", err
+ }
+
+ sc, err := cast.ToStringE(cutset)
+	if err != nil {+ return "", err
+ }
+
+ return _strings.TrimLeft(ss, sc), nil
+}
+
// TrimPrefix returns s without the provided leading prefix string. If s doesn't
// start with prefix, s is returned unchanged.
 func (ns *Namespace) TrimPrefix(s, prefix interface{}) (string, error) {@@ -361,6 +377,22 @@
}
return _strings.TrimPrefix(ss, sx), nil
+}
+
+// TrimRight returns a slice of the string s with all trailing characters
+// contained in cutset removed.
+func (ns *Namespace) TrimRight(cutset, s interface{}) (string, error) {+ ss, err := cast.ToStringE(s)
+	if err != nil {+ return "", err
+ }
+
+ sc, err := cast.ToStringE(cutset)
+	if err != nil {+ return "", err
+ }
+
+ return _strings.TrimRight(ss, sc), nil
}
// TrimSuffix returns s without the provided trailing suffix string. If s
--- a/tpl/strings/strings_test.go
+++ b/tpl/strings/strings_test.go
@@ -574,6 +574,41 @@
}
}
+func TestTrimLeft(t *testing.T) {+ t.Parallel()
+
+	for i, test := range []struct {+		s      interface{}+		cutset interface{}+		expect interface{}+	}{+		{"abba", "a", "bba"},+		{"abba", "ab", ""},+		{"<tag>", "<>", "tag>"},+		{`"quote"`, `"`, `quote"`},+		{1221, "1", "221"},+		{1221, "12", ""},+		{"007", "0", "7"},+		{template.HTML("<tag>"), "<>", "tag>"},+		{[]byte("<tag>"), "<>", "tag>"},+ // errors
+		{"", tstNoStringer{}, false},+		{tstNoStringer{}, "", false},+	} {+		errMsg := fmt.Sprintf("[%d] %v", i, test)+
+ result, err := ns.TrimLeft(test.cutset, test.s)
+
+		if b, ok := test.expect.(bool); ok && !b {+ require.Error(t, err, errMsg)
+ continue
+ }
+
+ require.NoError(t, err, errMsg)
+ assert.Equal(t, test.expect, result, errMsg)
+ }
+}
+
 func TestTrimPrefix(t *testing.T) {t.Parallel()
@@ -593,6 +628,41 @@
 		errMsg := fmt.Sprintf("[%d] %v", i, test)result, err := ns.TrimPrefix(test.s, test.prefix)
+
+		if b, ok := test.expect.(bool); ok && !b {+ require.Error(t, err, errMsg)
+ continue
+ }
+
+ require.NoError(t, err, errMsg)
+ assert.Equal(t, test.expect, result, errMsg)
+ }
+}
+
+func TestTrimRight(t *testing.T) {+ t.Parallel()
+
+	for i, test := range []struct {+		s      interface{}+		cutset interface{}+		expect interface{}+	}{+		{"abba", "a", "abb"},+		{"abba", "ab", ""},+		{"<tag>", "<>", "<tag"},+		{`"quote"`, `"`, `"quote`},+		{1221, "1", "122"},+		{1221, "12", ""},+		{"007", "0", "007"},+		{template.HTML("<tag>"), "<>", "<tag"},+		{[]byte("<tag>"), "<>", "<tag"},+ // errors
+		{"", tstNoStringer{}, false},+		{tstNoStringer{}, "", false},+	} {+		errMsg := fmt.Sprintf("[%d] %v", i, test)+
+ result, err := ns.TrimRight(test.cutset, test.s)
 		if b, ok := test.expect.(bool); ok && !b {require.Error(t, err, errMsg)
--
⑨