package sprig import ( "fmt" "math" "strconv" "strings" "github.com/spf13/cast" "github.com/shopspring/decimal" ) // toFloat64 converts 64-bit floats func toFloat64(v interface{}) float64 { return cast.ToFloat64(v) } func toInt(v interface{}) int { return cast.ToInt(v) } // toInt64 converts integer types to 64-bit integers func toInt64(v interface{}) int64 { return cast.ToInt64(v) } func max(a interface{}, i ...interface{}) int64 { aa := toInt64(a) for _, b := range i { bb := toInt64(b) if bb > aa { aa = bb } } return aa } func maxf(a interface{}, i ...interface{}) float64 { aa := toFloat64(a) for _, b := range i { bb := toFloat64(b) aa = math.Max(aa, bb) } return aa } func min(a interface{}, i ...interface{}) int64 { aa := toInt64(a) for _, b := range i { bb := toInt64(b) if bb < aa { aa = bb } } return aa } func minf(a interface{}, i ...interface{}) float64 { aa := toFloat64(a) for _, b := range i { bb := toFloat64(b) aa = math.Min(aa, bb) } return aa } func until(count int) []int { step := 1 if count < 0 { step = -1 } return untilStep(0, count, step) } func untilStep(start, stop, step int) []int { v := []int{} if stop < start { if step >= 0 { return v } for i := start; i > stop; i += step { v = append(v, i) } return v } if step <= 0 { return v } for i := start; i < stop; i += step { v = append(v, i) } return v } func floor(a interface{}) float64 { aa := toFloat64(a) return math.Floor(aa) } func ceil(a interface{}) float64 { aa := toFloat64(a) return math.Ceil(aa) } func round(a interface{}, p int, rOpt ...float64) float64 { roundOn := .5 if len(rOpt) > 0 { roundOn = rOpt[0] } val := toFloat64(a) places := toFloat64(p) var round float64 pow := math.Pow(10, places) digit := pow * val _, div := math.Modf(digit) if div >= roundOn { round = math.Ceil(digit) } else { round = math.Floor(digit) } return round / pow } // converts unix octal to decimal func toDecimal(v interface{}) int64 { result, err := strconv.ParseInt(fmt.Sprint(v), 8, 64) if err != nil { return 0 } return result } func seq(params ...int) string { increment := 1 switch len(params) { case 0: return "" case 1: start := 1 end := params[0] if end < start { increment = -1 } return intArrayToString(untilStep(start, end+increment, increment), " ") case 3: start := params[0] end := params[2] step := params[1] if end < start { increment = -1 if step > 0 { return "" } } return intArrayToString(untilStep(start, end+increment, step), " ") case 2: start := params[0] end := params[1] step := 1 if end < start { step = -1 } return intArrayToString(untilStep(start, end+step, step), " ") default: return "" } } func intArrayToString(slice []int, delimeter string) string { return strings.Trim(strings.Join(strings.Fields(fmt.Sprint(slice)), delimeter), "[]") } // performs a float and subsequent decimal.Decimal conversion on inputs, // and iterates through a and b executing the mathmetical operation f func execDecimalOp(a interface{}, b []interface{}, f func(d1, d2 decimal.Decimal) decimal.Decimal) float64 { prt := decimal.NewFromFloat(toFloat64(a)) for _, x := range b { dx := decimal.NewFromFloat(toFloat64(x)) prt = f(prt, dx) } rslt, _ := prt.Float64() return rslt }