mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
parent
d313bc78a4
commit
5b51b3b9fb
2 changed files with 76 additions and 42 deletions
|
@ -128,32 +128,65 @@ func compareGetFloat(a interface{}, b interface{}) (float64, float64) {
|
|||
return left, right
|
||||
}
|
||||
|
||||
// Taken out from Substr, to be used by Slicestr too.
|
||||
func toInt(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)
|
||||
}
|
||||
}
|
||||
|
||||
// Slicing in Slicestr is done by specifying a half-open range with
|
||||
// two indices, start and end. 1 and 4 creates a slice including elements 1 through 3.
|
||||
// The end index can be omitted, it defaults to the string's length.
|
||||
func Slicestr(a interface{}, startEnd ...int) (string, error) {
|
||||
func Slicestr(a interface{}, startEnd ...interface{}) (string, error) {
|
||||
aStr, err := cast.ToStringE(a)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(startEnd) > 2 {
|
||||
var argStart, argEnd int
|
||||
|
||||
argNum := len(startEnd)
|
||||
|
||||
if argNum > 0 {
|
||||
if argStart, err = toInt(startEnd[0], "start argument must be integer"); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
if argNum > 1 {
|
||||
if argEnd, err = toInt(startEnd[1], "end argument must be integer"); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if argNum > 2 {
|
||||
return "", errors.New("too many arguments")
|
||||
}
|
||||
|
||||
asRunes := []rune(aStr)
|
||||
|
||||
if len(startEnd) > 0 && (startEnd[0] < 0 || startEnd[0] >= len(asRunes)) {
|
||||
if argNum > 0 && (argStart < 0 || argStart >= len(asRunes)) {
|
||||
return "", errors.New("slice bounds out of range")
|
||||
}
|
||||
|
||||
if len(startEnd) == 2 {
|
||||
if startEnd[1] < 0 || startEnd[1] > len(asRunes) {
|
||||
if argNum == 2 {
|
||||
if argEnd < 0 || argEnd > len(asRunes) {
|
||||
return "", errors.New("slice bounds out of range")
|
||||
}
|
||||
return string(asRunes[startEnd[0]:startEnd[1]]), nil
|
||||
} else if len(startEnd) == 1 {
|
||||
return string(asRunes[startEnd[0]:]), nil
|
||||
return string(asRunes[argStart:argEnd]), nil
|
||||
} else if argNum == 1 {
|
||||
return string(asRunes[argStart:]), nil
|
||||
} else {
|
||||
return string(asRunes[:]), nil
|
||||
}
|
||||
|
@ -179,22 +212,6 @@ func Substr(a interface{}, nums ...interface{}) (string, error) {
|
|||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
asRunes := []rune(aStr)
|
||||
|
||||
|
|
|
@ -348,29 +348,46 @@ func TestIn(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSlicestr(t *testing.T) {
|
||||
var err error
|
||||
for i, this := range []struct {
|
||||
v1 interface{}
|
||||
v2 []int
|
||||
v2 interface{}
|
||||
v3 interface{}
|
||||
expect interface{}
|
||||
}{
|
||||
{"abc", []int{1, 2}, "b"},
|
||||
{"abc", []int{1, 3}, "bc"},
|
||||
{"abc", []int{0, 1}, "a"},
|
||||
{"abcdef", []int{}, "abcdef"},
|
||||
{"abcdef", []int{0, 6}, "abcdef"},
|
||||
{"abcdef", []int{0, 2}, "ab"},
|
||||
{"abcdef", []int{2}, "cdef"},
|
||||
{123, []int{1, 3}, "23"},
|
||||
{123, []int{1, 2, 3}, false},
|
||||
{"abcdef", []int{6}, false},
|
||||
{"abcdef", []int{4, 7}, false},
|
||||
{"abcdef", []int{-1}, false},
|
||||
{"abcdef", []int{-1, 7}, false},
|
||||
{"abcdef", []int{1, -1}, false},
|
||||
{tstNoStringer{}, []int{0, 1}, false},
|
||||
{"ĀĀĀ", []int{0, 1}, "Ā"}, // issue #1333
|
||||
{"abc", 1, 2, "b"},
|
||||
{"abc", 1, 3, "bc"},
|
||||
{"abcdef", 1, int8(3), "bc"},
|
||||
{"abcdef", 1, int16(3), "bc"},
|
||||
{"abcdef", 1, int32(3), "bc"},
|
||||
{"abcdef", 1, int64(3), "bc"},
|
||||
{"abc", 0, 1, "a"},
|
||||
{"abcdef", nil, nil, "abcdef"},
|
||||
{"abcdef", 0, 6, "abcdef"},
|
||||
{"abcdef", 0, 2, "ab"},
|
||||
{"abcdef", 2, nil, "cdef"},
|
||||
{"abcdef", int8(2), nil, "cdef"},
|
||||
{"abcdef", int16(2), nil, "cdef"},
|
||||
{"abcdef", int32(2), nil, "cdef"},
|
||||
{"abcdef", int64(2), nil, "cdef"},
|
||||
{123, 1, 3, "23"},
|
||||
{"abcdef", 6, nil, false},
|
||||
{"abcdef", 4, 7, false},
|
||||
{"abcdef", -1, nil, false},
|
||||
{"abcdef", -1, 7, false},
|
||||
{"abcdef", 1, -1, false},
|
||||
{tstNoStringer{}, 0, 1, false},
|
||||
{"ĀĀĀ", 0, 1, "Ā"}, // issue #1333
|
||||
} {
|
||||
result, err := Slicestr(this.v1, this.v2...)
|
||||
|
||||
var result string
|
||||
if this.v2 == nil {
|
||||
result, err = Slicestr(this.v1)
|
||||
} else if this.v3 == nil {
|
||||
result, err = Slicestr(this.v1, this.v2)
|
||||
} else {
|
||||
result, err = Slicestr(this.v1, this.v2, this.v3)
|
||||
}
|
||||
|
||||
if b, ok := this.expect.(bool); ok && !b {
|
||||
if err == nil {
|
||||
|
|
Loading…
Reference in a new issue