Adds expr functions

- modWeek returns modify week part of the date input
- random returns random number between range if given
- sub returns diff between two dates in milliseconds
This commit is contained in:
Vivek Patel
2021-08-24 14:08:39 +05:30
parent 626f03a9e7
commit e4a59a5f03
4 changed files with 129 additions and 2 deletions
+31 -2
View File
@@ -1,9 +1,10 @@
package expr
import (
"math"
"github.com/PaesslerAG/gval"
"github.com/pkg/errors"
"math"
"math/rand"
)
func NumericFunctions() []gval.Language {
@@ -19,6 +20,7 @@ func NumericFunctions() []gval.Language {
gval.Function("sqrt", math.Sqrt),
gval.Function("sum", sum),
gval.Function("average", average),
gval.Function("random", random),
}
}
@@ -112,3 +114,30 @@ func average(v ...interface{}) float64 {
return sum / j
}
func random(v ...float64) (out float64, err error) {
var (
from, to float64
totalArgs = len(v)
)
if totalArgs == 0 || totalArgs > 2 {
return 0, errors.Errorf("expecting 1 or 2 parameter, got %d", totalArgs)
}
if totalArgs > 0 {
if to = v[0]; to < 0 {
return 0, errors.New("unexpected input type of 1st parameter")
}
}
if totalArgs > 1 {
if to = v[1]; to < 0 {
return 0, errors.New("unexpected input type of 2nd parameter")
}
from = v[0]
}
out = from + rand.Float64()*(to-from)
return
}
+14
View File
@@ -76,3 +76,17 @@ func Example_average() {
// output:
// 4
}
func Example_randomWithSingleInput() {
eval(`max(random(6), 7)`, nil)
// output:
// 7
}
func Example_randomWithTwoInput() {
eval(`min(random(2, 6), 1)`, nil)
// output:
// 1
}
+35
View File
@@ -16,6 +16,7 @@ func TimeFunctions() []gval.Language {
gval.Function("parseISOTime", parseISOTime),
gval.Function("modTime", modTime),
gval.Function("modDate", modDate),
gval.Function("modWeek", modWeek),
gval.Function("modMonth", modMonth),
gval.Function("modYear", modYear),
gval.Function("parseDuration", time.ParseDuration),
@@ -23,6 +24,7 @@ func TimeFunctions() []gval.Language {
gval.Function("isLeapYear", isLeapYear),
gval.Function("now", now),
gval.Function("isWeekDay", isWeekDay),
gval.Function("sub", sub),
}
}
@@ -131,6 +133,16 @@ func modDate(base interface{}, mod interface{}) (*time.Time, error) {
return &tmp, nil
}
func modWeek(base interface{}, mod interface{}) (*time.Time, error) {
t, m, err := prepMod(base, mod)
if err != nil {
return nil, err
}
tmp := t.AddDate(0, 0, 7*m)
return &tmp, nil
}
func modMonth(base interface{}, mod interface{}) (*time.Time, error) {
t, m, err := prepMod(base, mod)
if err != nil {
@@ -184,3 +196,26 @@ func strfTime(base interface{}, f string) (string, error) {
o, _ := strftime.Format(f, *t, strftime.WithMilliseconds('b'))
return o, nil
}
// sub returns difference between two date into milliseconds
func sub(from interface{}, to interface{}) (out int64, err error) {
t1, _, err := prepMod(from, 0)
if err != nil {
return
}
t2, _, err := prepMod(to, 0)
if err != nil {
return
}
var duration time.Duration
if t1.After(*t2) {
duration = t1.Sub(*t2)
} else {
return -1, errors.New("expecting 2nd input to be less than 1st input")
}
return duration.Milliseconds(), nil
}
+49
View File
@@ -85,3 +85,52 @@ func Example_isWeekDay() {
// output:
// true
}
func Example_modTime() {
eval(`modTime(ghd, "+30m")`, exampleTimeParams)
// output:
// 1993-02-02 06:30:00 -0500 -0500
}
func Example_modWeek() {
eval(`modWeek(ghd, "1")`, exampleTimeParams)
// output:
// 1993-02-09 06:00:00 -0500 -0500
}
func Example_modDate() {
eval(`modDate(ghd, "5")`, exampleTimeParams)
// output:
// 1993-02-07 06:00:00 -0500 -0500
}
func Example_modMonth() {
eval(`modMonth(ghd, "1")`, exampleTimeParams)
// output:
// 1993-03-02 06:00:00 -0500 -0500
}
func Example_modYear() {
eval(`modYear(ghd, "5")`, exampleTimeParams)
// output:
// 1998-02-02 06:00:00 -0500 -0500
}
func Example_sub() {
eval(`sub(hgp, ghd)`, exampleTimeParams)
// output:
// 321627600000
}
func Example_subErrorCheck() {
eval(`sub(ghd, hgp)`, exampleTimeParams)
// output:
// error: can not evaluate sub(ghd, hgp): expecting 2nd input to be less than 1st input
}