mirror of
https://github.com/gohugoio/hugo.git
synced 2025-03-20 02:31:50 +00:00
Fix substr tpl func's int type variant issue
`substr` template function takes one or two range arguments. Both arguments must be int type values but if it is used with a calclation function e.g. `add`, `len` etc, it causes a wrong type error. This fixes the issue to allow the function to take other integer type variant like `int64` etc. This also includes a small fix on no range argument case. Fix #1190
This commit is contained in:
parent
be44345272
commit
51cabe6faf
2 changed files with 65 additions and 7 deletions
|
@ -170,20 +170,45 @@ func Slicestr(a interface{}, startEnd ...int) (string, error) {
|
||||||
// In addition, borrowing from the extended behavior described at http://php.net/substr,
|
// In addition, borrowing from the extended behavior described at http://php.net/substr,
|
||||||
// if length is given and is negative, then that many characters will be omitted from
|
// if length is given and is negative, then that many characters will be omitted from
|
||||||
// the end of string.
|
// the end of string.
|
||||||
func Substr(a interface{}, nums ...int) (string, error) {
|
func Substr(a interface{}, nums ...interface{}) (string, error) {
|
||||||
aStr, err := cast.ToStringE(a)
|
aStr, err := cast.ToStringE(a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
var start, length int
|
var start, length int
|
||||||
|
toInt := func (v interface{}, message string) (int, error) {
|
||||||
|
switch i := v.(type) {
|
||||||
|
case int:
|
||||||
|
return i, nil
|
||||||
|
case int8:
|
||||||
|
return int(i), nil
|
||||||
|
case int16:
|
||||||
|
return int(i), nil
|
||||||
|
case int32:
|
||||||
|
return int(i), nil
|
||||||
|
case int64:
|
||||||
|
return int(i), nil
|
||||||
|
default:
|
||||||
|
return 0, errors.New(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch len(nums) {
|
switch len(nums) {
|
||||||
|
case 0:
|
||||||
|
return "", errors.New("too less arguments")
|
||||||
case 1:
|
case 1:
|
||||||
start = nums[0]
|
if start, err = toInt(nums[0], "start argument must be integer"); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
length = len(aStr)
|
length = len(aStr)
|
||||||
case 2:
|
case 2:
|
||||||
start = nums[0]
|
if start, err = toInt(nums[0], "start argument must be integer"); err != nil {
|
||||||
length = nums[1]
|
return "", err
|
||||||
|
}
|
||||||
|
if length, err = toInt(nums[1], "length argument must be integer"); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return "", errors.New("too many arguments")
|
return "", errors.New("too many arguments")
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,10 +317,12 @@ func TestSlicestr(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSubstr(t *testing.T) {
|
func TestSubstr(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
var n int
|
||||||
for i, this := range []struct {
|
for i, this := range []struct {
|
||||||
v1 interface{}
|
v1 interface{}
|
||||||
v2 int
|
v2 interface{}
|
||||||
v3 int
|
v3 interface{}
|
||||||
expect interface{}
|
expect interface{}
|
||||||
}{
|
}{
|
||||||
{"abc", 1, 2, "bc"},
|
{"abc", 1, 2, "bc"},
|
||||||
|
@ -334,11 +336,30 @@ func TestSubstr(t *testing.T) {
|
||||||
{"abcdef", 1, 100, "bcdef"},
|
{"abcdef", 1, 100, "bcdef"},
|
||||||
{"abcdef", -100, 3, "abc"},
|
{"abcdef", -100, 3, "abc"},
|
||||||
{"abcdef", -3, -1, "de"},
|
{"abcdef", -3, -1, "de"},
|
||||||
|
{"abcdef", 2, nil, "cdef"},
|
||||||
|
{"abcdef", int8(2), nil, "cdef"},
|
||||||
|
{"abcdef", int16(2), nil, "cdef"},
|
||||||
|
{"abcdef", int32(2), nil, "cdef"},
|
||||||
|
{"abcdef", int64(2), nil, "cdef"},
|
||||||
|
{"abcdef", 2, int8(3), "cde"},
|
||||||
|
{"abcdef", 2, int16(3), "cde"},
|
||||||
|
{"abcdef", 2, int32(3), "cde"},
|
||||||
|
{"abcdef", 2, int64(3), "cde"},
|
||||||
{123, 1, 3, "23"},
|
{123, 1, 3, "23"},
|
||||||
{1.2e3, 0, 4, "1200"},
|
{1.2e3, 0, 4, "1200"},
|
||||||
{tstNoStringer{}, 0, 1, false},
|
{tstNoStringer{}, 0, 1, false},
|
||||||
|
{"abcdef", 2.0, nil, false},
|
||||||
|
{"abcdef", 2.0, 2, false},
|
||||||
|
{"abcdef", 2, 2.0, false},
|
||||||
} {
|
} {
|
||||||
result, err := Substr(this.v1, this.v2, this.v3)
|
var result string
|
||||||
|
n = i
|
||||||
|
|
||||||
|
if this.v3 == nil {
|
||||||
|
result, err = Substr(this.v1, this.v2)
|
||||||
|
} else {
|
||||||
|
result, err = Substr(this.v1, this.v2, this.v3)
|
||||||
|
}
|
||||||
|
|
||||||
if b, ok := this.expect.(bool); ok && !b {
|
if b, ok := this.expect.(bool); ok && !b {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -354,6 +375,18 @@ func TestSubstr(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n++
|
||||||
|
_, err = Substr("abcdef")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("[%d] Substr didn't return an expected error", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
n++
|
||||||
|
_, err = Substr("abcdef", 1, 2, 3)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("[%d] Substr didn't return an expected error", n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSplit(t *testing.T) {
|
func TestSplit(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue