func replaceFirst(s string, args ...string) string {
	switch len(args) {
	case 0:
		return s
	case 1:
		return strings.Replace(s, args[0], "", 1)
	default:
		return strings.Replace(s, args[0], args[1], 1)
	}
}
replaceFirst returns a copy of the string s with the first
instance of the substring replaced with the replacement string.
package envsubst
import (
	"strconv"
	"strings"
	"unicode"
	"unicode/utf8"
	"github.com/drone/envsubst/v2/path"
)
type substituteFunc func(string, ...string) string
func toLen(s string, args ...string) string {
	return strconv.Itoa(len(s))
}
func toLower(s string, args ...string) string {
	return strings.ToLower(s)
}
func toUpper(s string, args ...string) string {
	return strings.ToUpper(s)
}
func toLowerFirst(s string, args ...string) string {
	if s == "" {
		return s
	}
	r, n := utf8.DecodeRuneInString(s)
	return string(unicode.ToLower(r)) + s[n:]
}
func toUpperFirst(s string, args ...string) string {
	if s == "" {
		return s
	}
	r, n := utf8.DecodeRuneInString(s)
	return string(unicode.ToUpper(r)) + s[n:]
}
func toDefault(s string, args ...string) string {
	if len(s) == 0 && len(args) > 0 {
		s = strings.Join(args, "")
	}
	return s
}
func toSubstr(s string, args ...string) string {
	if len(args) == 0 {
		return s  
	}
	pos, err := strconv.Atoi(args[0])
	if err != nil {
		return s
	}
	if pos < 0 {
		pos = len(s) + pos
		if pos < 0 {
			pos = 0
		}
	}
	if len(args) == 1 {
		if pos < len(s) {
			return s[pos:]
		}
		return ""
	}
	length, err := strconv.Atoi(args[1])
	if err != nil {
		return s
	}
	if pos+length >= len(s) {
		if pos < len(s) {
			return s[pos:]
		}
		return ""
	}
	return s[pos : pos+length]
}
func replaceAll(s string, args ...string) string {
	switch len(args) {
	case 0:
		return s
	case 1:
		return strings.Replace(s, args[0], "", -1)
	default:
		return strings.Replace(s, args[0], args[1], -1)
	}
}