diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cb24fac3..3616e546 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -31,10 +31,12 @@ jobs: uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} + - if: ${{ !startsWith(github.ref, 'refs/tags/') }} + run: echo "flags=--snapshot" >> $GITHUB_ENV - name: Run GoReleaser uses: goreleaser/goreleaser-action@v6.1.0 with: version: v2.5.0 - args: release + args: release --clean ${{ env.flags }} env: GITHUB_TOKEN: ${{ secrets.GITHUBTOKEN }} diff --git a/docs/usage/expressions.md b/docs/usage/expressions.md index 6685d606..d8173e2b 100644 --- a/docs/usage/expressions.md +++ b/docs/usage/expressions.md @@ -114,9 +114,9 @@ Create exponentially (base-10) increase buckets. ### Arithmetic -#### Sumi, Subi, Multi, Divi +#### Sumi, Subi, Multi, Divi, Modi -Syntax: `{sumi ...}`, `{subi ...}`, `{multi ...}`, `{divi ...}` +Syntax: `{sumi ...}`, `{subi ...}`, `{multi ...}`, `{divi ...}`, `{modi ...}` Evaluates integers using operator from left to right. Requires at least 2 arguments. @@ -146,6 +146,12 @@ Returns the floor, ceil, or rounded format of a floating-point number. Eg: `{floor 123.765}` will result in `123` +#### log, pow, sqrt + +Syntax: `{log10 val}`, `{log2 val}`, `{ln val}`, `{pow val exp}`, `{sqrt val}` + +Returns the log (10, 2, or natural), power, or sqrt of a floating-point number. + #### Clamp Syntax: `{clamp intVal "min" "max"}` diff --git a/pkg/expressions/stdlib/funcs.go b/pkg/expressions/stdlib/funcs.go index b19704c6..7efe6c46 100644 --- a/pkg/expressions/stdlib/funcs.go +++ b/pkg/expressions/stdlib/funcs.go @@ -21,6 +21,7 @@ var StandardFunctions = map[string]KeyBuilderFunction{ "subi": arithmaticHelperi(func(a, b int) int { return a - b }), "multi": arithmaticHelperi(func(a, b int) int { return a * b }), "divi": arithmaticHelperi(func(a, b int) int { return a / b }), + "modi": arithmaticHelperi(func(a, b int) int { return a % b }), "maxi": arithmaticHelperi(func(a, b int) int { if a > b { return a @@ -39,6 +40,11 @@ var StandardFunctions = map[string]KeyBuilderFunction{ "divf": arithmaticHelperf(func(a, b float64) float64 { return a / b }), "ceil": unaryArithmaticHelperfi(func(f float64) int64 { return int64(math.Ceil(f)) }), "floor": unaryArithmaticHelperfi(func(f float64) int64 { return int64(math.Floor(f)) }), + "log10": unaryArithmaticHelperf(math.Log10), + "log2": unaryArithmaticHelperf(math.Log2), + "ln": unaryArithmaticHelperf(math.Log), + "pow": arithmaticHelperf(math.Pow), + "sqrt": unaryArithmaticHelperf(math.Sqrt), "round": kfRound, // Comparisons diff --git a/pkg/expressions/stdlib/funcsArithmatic.go b/pkg/expressions/stdlib/funcsArithmatic.go index 75a94cb2..c0e88a26 100644 --- a/pkg/expressions/stdlib/funcsArithmatic.go +++ b/pkg/expressions/stdlib/funcsArithmatic.go @@ -55,6 +55,24 @@ func arithmaticHelperf(equation func(float64, float64) float64) KeyBuilderFuncti }) } +// Helper that takes in a float, operates on it +func unaryArithmaticHelperf(op func(float64) float64) KeyBuilderFunction { + return func(args []KeyBuilderStage) (KeyBuilderStage, error) { + if len(args) != 1 { + return stageErrArgCount(args, 1) + } + + return func(context KeyBuilderContext) string { + val, err := strconv.ParseFloat(args[0](context), 64) + if err != nil { + return ErrorNum + } + + return strconv.FormatFloat(op(val), 'f', -1, 64) + }, nil + } +} + // Helper that takes in a float, operates on it, and spits out an int func unaryArithmaticHelperfi(op func(float64) int64) KeyBuilderFunction { return func(args []KeyBuilderStage) (KeyBuilderStage, error) { diff --git a/pkg/expressions/stdlib/funcsArithmatic_test.go b/pkg/expressions/stdlib/funcsArithmatic_test.go index a9bec892..f2dd69a9 100644 --- a/pkg/expressions/stdlib/funcsArithmatic_test.go +++ b/pkg/expressions/stdlib/funcsArithmatic_test.go @@ -7,9 +7,9 @@ import ( ) func TestArithmatic(t *testing.T) { - kb, _ := NewStdKeyBuilder().Compile("{sumi {1} {4}} {multi {1} 2} {divi {1} 2} {subi {1} 10}") + kb, _ := NewStdKeyBuilder().Compile("{sumi {1} {4}} {multi {1} 2} {divi {1} 2} {subi {1} 10} {modi {1} 7}") key := kb.BuildKey(mockContext("ab", "100", "1000000", "5000000.123456", "22")) - assert.Equal(t, "122 200 50 90", key) + assert.Equal(t, "122 200 50 90 2", key) } func TestArithmaticError(t *testing.T) { @@ -45,3 +45,13 @@ func TestFloorCeilRound(t *testing.T) { testExpressionErr(t, mockContext("123.123"), "{round {0} {0}}", "", ErrConst) testExpressionErr(t, mockContext("123.123"), "{round {0} b}", "", ErrConst) } + +func TestLogPow(t *testing.T) { + testExpression(t, mockContext("100"), "{log10 {0}}", "2") + testExpression(t, mockContext("64"), "{log2 {0}}", "6") + testExpression(t, mockContext("64"), "{round {ln {0}} 4}", "4.1589") + testExpression(t, mockContext("3"), "{pow {0} 3}", "27") + testExpression(t, mockContext("81"), "{sqrt {0}}", "9") + + testExpressionErr(t, mockContext(), "{sqrt 1 2}", "", ErrArgCount) +}