func()

in lib/strings.go [797:842]


func (l stringLib) substring(args ...ref.Val) ref.Val {
	if len(args) != 3 {
		return types.NewErr("no such overload for substring")
	}
	s, ok := args[0].(types.String)
	if !ok {
		return types.ValOrErr(s, "no such overload for substring")
	}
	start, ok := args[1].(types.Int)
	if !ok {
		return types.ValOrErr(start, "no such overload for substring")
	}
	if start < 0 {
		return types.NewErr("substring: start out of range: %d < 0", start)
	}
	end, ok := args[2].(types.Int)
	if !ok {
		return types.ValOrErr(end, "no such overload for substring")
	}
	if end < start {
		return types.NewErr("substring: end out of range: %d < %d", end, start)
	}
	i, pos, left := 0, 0, -1
	for ; pos <= len(s); i++ {
		if i == int(start) {
			left = pos
		}
		if i == int(end) {
			// TODO: Consider adding a heuristic to decide if the
			// substring should be cloned to avoid pinning s.
			return types.DefaultTypeAdapter.NativeToValue(s[left:pos])
		}
		if pos == len(s) {
			break
		}
		r, size := utf8.DecodeRuneInString(string(s[pos:]))
		if r == utf8.RuneError {
			return types.NewErr("substring: invalid rune at position %d in string: %s", pos, s)
		}
		pos += size
	}
	if left == -1 {
		return types.NewErr("substring: start out of range: %d > %d", start, i)
	}
	return types.NewErr("substring: end out of range: %d > %d", end, i)
}