summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/d5/tengo/v2/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/d5/tengo/v2/stdlib')
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/base64.go34
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/builtin_modules.go18
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/errors.go12
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/fmt.go101
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/func_typedefs.go1049
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/hex.go12
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/json.go146
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/json/decode.go358
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/json/encode.go146
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/json/scanner.go562
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/math.go233
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/os.go564
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/os_exec.go119
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/os_file.go117
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/os_process.go76
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/rand.go138
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/source_modules.go8
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/srcmod_enum.tengo128
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/stdlib.go34
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/text.go1072
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/text_regexp.go251
-rw-r--r--vendor/github.com/d5/tengo/v2/stdlib/times.go1135
22 files changed, 6313 insertions, 0 deletions
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/base64.go b/vendor/github.com/d5/tengo/v2/stdlib/base64.go
new file mode 100644
index 00000000..b4c5b56e
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/base64.go
@@ -0,0 +1,34 @@
+package stdlib
+
+import (
+ "encoding/base64"
+
+ "github.com/d5/tengo/v2"
+)
+
+var base64Module = map[string]tengo.Object{
+ "encode": &tengo.UserFunction{
+ Value: FuncAYRS(base64.StdEncoding.EncodeToString),
+ },
+ "decode": &tengo.UserFunction{
+ Value: FuncASRYE(base64.StdEncoding.DecodeString),
+ },
+ "raw_encode": &tengo.UserFunction{
+ Value: FuncAYRS(base64.RawStdEncoding.EncodeToString),
+ },
+ "raw_decode": &tengo.UserFunction{
+ Value: FuncASRYE(base64.RawStdEncoding.DecodeString),
+ },
+ "url_encode": &tengo.UserFunction{
+ Value: FuncAYRS(base64.URLEncoding.EncodeToString),
+ },
+ "url_decode": &tengo.UserFunction{
+ Value: FuncASRYE(base64.URLEncoding.DecodeString),
+ },
+ "raw_url_encode": &tengo.UserFunction{
+ Value: FuncAYRS(base64.RawURLEncoding.EncodeToString),
+ },
+ "raw_url_decode": &tengo.UserFunction{
+ Value: FuncASRYE(base64.RawURLEncoding.DecodeString),
+ },
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/builtin_modules.go b/vendor/github.com/d5/tengo/v2/stdlib/builtin_modules.go
new file mode 100644
index 00000000..cf0e9621
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/builtin_modules.go
@@ -0,0 +1,18 @@
+package stdlib
+
+import (
+ "github.com/d5/tengo/v2"
+)
+
+// BuiltinModules are builtin type standard library modules.
+var BuiltinModules = map[string]map[string]tengo.Object{
+ "math": mathModule,
+ "os": osModule,
+ "text": textModule,
+ "times": timesModule,
+ "rand": randModule,
+ "fmt": fmtModule,
+ "json": jsonModule,
+ "base64": base64Module,
+ "hex": hexModule,
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/errors.go b/vendor/github.com/d5/tengo/v2/stdlib/errors.go
new file mode 100644
index 00000000..ad83c6f8
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/errors.go
@@ -0,0 +1,12 @@
+package stdlib
+
+import (
+ "github.com/d5/tengo/v2"
+)
+
+func wrapError(err error) tengo.Object {
+ if err == nil {
+ return tengo.TrueValue
+ }
+ return &tengo.Error{Value: &tengo.String{Value: err.Error()}}
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/fmt.go b/vendor/github.com/d5/tengo/v2/stdlib/fmt.go
new file mode 100644
index 00000000..9945277f
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/fmt.go
@@ -0,0 +1,101 @@
+package stdlib
+
+import (
+ "fmt"
+
+ "github.com/d5/tengo/v2"
+)
+
+var fmtModule = map[string]tengo.Object{
+ "print": &tengo.UserFunction{Name: "print", Value: fmtPrint},
+ "printf": &tengo.UserFunction{Name: "printf", Value: fmtPrintf},
+ "println": &tengo.UserFunction{Name: "println", Value: fmtPrintln},
+ "sprintf": &tengo.UserFunction{Name: "sprintf", Value: fmtSprintf},
+}
+
+func fmtPrint(args ...tengo.Object) (ret tengo.Object, err error) {
+ printArgs, err := getPrintArgs(args...)
+ if err != nil {
+ return nil, err
+ }
+ _, _ = fmt.Print(printArgs...)
+ return nil, nil
+}
+
+func fmtPrintf(args ...tengo.Object) (ret tengo.Object, err error) {
+ numArgs := len(args)
+ if numArgs == 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+
+ format, ok := args[0].(*tengo.String)
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "format",
+ Expected: "string",
+ Found: args[0].TypeName(),
+ }
+ }
+ if numArgs == 1 {
+ fmt.Print(format)
+ return nil, nil
+ }
+
+ s, err := tengo.Format(format.Value, args[1:]...)
+ if err != nil {
+ return nil, err
+ }
+ fmt.Print(s)
+ return nil, nil
+}
+
+func fmtPrintln(args ...tengo.Object) (ret tengo.Object, err error) {
+ printArgs, err := getPrintArgs(args...)
+ if err != nil {
+ return nil, err
+ }
+ printArgs = append(printArgs, "\n")
+ _, _ = fmt.Print(printArgs...)
+ return nil, nil
+}
+
+func fmtSprintf(args ...tengo.Object) (ret tengo.Object, err error) {
+ numArgs := len(args)
+ if numArgs == 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+
+ format, ok := args[0].(*tengo.String)
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "format",
+ Expected: "string",
+ Found: args[0].TypeName(),
+ }
+ }
+ if numArgs == 1 {
+ // okay to return 'format' directly as String is immutable
+ return format, nil
+ }
+ s, err := tengo.Format(format.Value, args[1:]...)
+ if err != nil {
+ return nil, err
+ }
+ return &tengo.String{Value: s}, nil
+}
+
+func getPrintArgs(args ...tengo.Object) ([]interface{}, error) {
+ var printArgs []interface{}
+ l := 0
+ for _, arg := range args {
+ s, _ := tengo.ToString(arg)
+ slen := len(s)
+ // make sure length does not exceed the limit
+ if l+slen > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ l += slen
+ printArgs = append(printArgs, s)
+ }
+ return printArgs, nil
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/func_typedefs.go b/vendor/github.com/d5/tengo/v2/stdlib/func_typedefs.go
new file mode 100644
index 00000000..fdac933c
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/func_typedefs.go
@@ -0,0 +1,1049 @@
+package stdlib
+
+import (
+ "fmt"
+
+ "github.com/d5/tengo/v2"
+)
+
+// FuncAR transform a function of 'func()' signature into CallableFunc type.
+func FuncAR(fn func()) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ fn()
+ return tengo.UndefinedValue, nil
+ }
+}
+
+// FuncARI transform a function of 'func() int' signature into CallableFunc
+// type.
+func FuncARI(fn func() int) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ return &tengo.Int{Value: int64(fn())}, nil
+ }
+}
+
+// FuncARI64 transform a function of 'func() int64' signature into CallableFunc
+// type.
+func FuncARI64(fn func() int64) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ return &tengo.Int{Value: fn()}, nil
+ }
+}
+
+// FuncAI64RI64 transform a function of 'func(int64) int64' signature into
+// CallableFunc type.
+func FuncAI64RI64(fn func(int64) int64) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+
+ i1, ok := tengo.ToInt64(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ return &tengo.Int{Value: fn(i1)}, nil
+ }
+}
+
+// FuncAI64R transform a function of 'func(int64)' signature into CallableFunc
+// type.
+func FuncAI64R(fn func(int64)) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+
+ i1, ok := tengo.ToInt64(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ fn(i1)
+ return tengo.UndefinedValue, nil
+ }
+}
+
+// FuncARB transform a function of 'func() bool' signature into CallableFunc
+// type.
+func FuncARB(fn func() bool) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ if fn() {
+ return tengo.TrueValue, nil
+ }
+ return tengo.FalseValue, nil
+ }
+}
+
+// FuncARE transform a function of 'func() error' signature into CallableFunc
+// type.
+func FuncARE(fn func() error) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ return wrapError(fn()), nil
+ }
+}
+
+// FuncARS transform a function of 'func() string' signature into CallableFunc
+// type.
+func FuncARS(fn func() string) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s := fn()
+ if len(s) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ return &tengo.String{Value: s}, nil
+ }
+}
+
+// FuncARSE transform a function of 'func() (string, error)' signature into
+// CallableFunc type.
+func FuncARSE(fn func() (string, error)) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ res, err := fn()
+ if err != nil {
+ return wrapError(err), nil
+ }
+ if len(res) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ return &tengo.String{Value: res}, nil
+ }
+}
+
+// FuncARYE transform a function of 'func() ([]byte, error)' signature into
+// CallableFunc type.
+func FuncARYE(fn func() ([]byte, error)) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ res, err := fn()
+ if err != nil {
+ return wrapError(err), nil
+ }
+ if len(res) > tengo.MaxBytesLen {
+ return nil, tengo.ErrBytesLimit
+ }
+ return &tengo.Bytes{Value: res}, nil
+ }
+}
+
+// FuncARF transform a function of 'func() float64' signature into CallableFunc
+// type.
+func FuncARF(fn func() float64) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ return &tengo.Float{Value: fn()}, nil
+ }
+}
+
+// FuncARSs transform a function of 'func() []string' signature into
+// CallableFunc type.
+func FuncARSs(fn func() []string) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ arr := &tengo.Array{}
+ for _, elem := range fn() {
+ if len(elem) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ arr.Value = append(arr.Value, &tengo.String{Value: elem})
+ }
+ return arr, nil
+ }
+}
+
+// FuncARIsE transform a function of 'func() ([]int, error)' signature into
+// CallableFunc type.
+func FuncARIsE(fn func() ([]int, error)) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ res, err := fn()
+ if err != nil {
+ return wrapError(err), nil
+ }
+ arr := &tengo.Array{}
+ for _, v := range res {
+ arr.Value = append(arr.Value, &tengo.Int{Value: int64(v)})
+ }
+ return arr, nil
+ }
+}
+
+// FuncAIRIs transform a function of 'func(int) []int' signature into
+// CallableFunc type.
+func FuncAIRIs(fn func(int) []int) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ i1, ok := tengo.ToInt(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ res := fn(i1)
+ arr := &tengo.Array{}
+ for _, v := range res {
+ arr.Value = append(arr.Value, &tengo.Int{Value: int64(v)})
+ }
+ return arr, nil
+ }
+}
+
+// FuncAFRF transform a function of 'func(float64) float64' signature into
+// CallableFunc type.
+func FuncAFRF(fn func(float64) float64) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ f1, ok := tengo.ToFloat64(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "float(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ return &tengo.Float{Value: fn(f1)}, nil
+ }
+}
+
+// FuncAIR transform a function of 'func(int)' signature into CallableFunc type.
+func FuncAIR(fn func(int)) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ i1, ok := tengo.ToInt(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ fn(i1)
+ return tengo.UndefinedValue, nil
+ }
+}
+
+// FuncAIRF transform a function of 'func(int) float64' signature into
+// CallableFunc type.
+func FuncAIRF(fn func(int) float64) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ i1, ok := tengo.ToInt(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ return &tengo.Float{Value: fn(i1)}, nil
+ }
+}
+
+// FuncAFRI transform a function of 'func(float64) int' signature into
+// CallableFunc type.
+func FuncAFRI(fn func(float64) int) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ f1, ok := tengo.ToFloat64(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "float(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ return &tengo.Int{Value: int64(fn(f1))}, nil
+ }
+}
+
+// FuncAFFRF transform a function of 'func(float64, float64) float64' signature
+// into CallableFunc type.
+func FuncAFFRF(fn func(float64, float64) float64) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ f1, ok := tengo.ToFloat64(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "float(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ f2, ok := tengo.ToFloat64(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "float(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ return &tengo.Float{Value: fn(f1, f2)}, nil
+ }
+}
+
+// FuncAIFRF transform a function of 'func(int, float64) float64' signature
+// into CallableFunc type.
+func FuncAIFRF(fn func(int, float64) float64) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ i1, ok := tengo.ToInt(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ f2, ok := tengo.ToFloat64(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "float(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ return &tengo.Float{Value: fn(i1, f2)}, nil
+ }
+}
+
+// FuncAFIRF transform a function of 'func(float64, int) float64' signature
+// into CallableFunc type.
+func FuncAFIRF(fn func(float64, int) float64) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ f1, ok := tengo.ToFloat64(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "float(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ return &tengo.Float{Value: fn(f1, i2)}, nil
+ }
+}
+
+// FuncAFIRB transform a function of 'func(float64, int) bool' signature
+// into CallableFunc type.
+func FuncAFIRB(fn func(float64, int) bool) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ f1, ok := tengo.ToFloat64(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "float(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ if fn(f1, i2) {
+ return tengo.TrueValue, nil
+ }
+ return tengo.FalseValue, nil
+ }
+}
+
+// FuncAFRB transform a function of 'func(float64) bool' signature
+// into CallableFunc type.
+func FuncAFRB(fn func(float64) bool) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ f1, ok := tengo.ToFloat64(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "float(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ if fn(f1) {
+ return tengo.TrueValue, nil
+ }
+ return tengo.FalseValue, nil
+ }
+}
+
+// FuncASRS transform a function of 'func(string) string' signature into
+// CallableFunc type. User function will return 'true' if underlying native
+// function returns nil.
+func FuncASRS(fn func(string) string) tengo.CallableFunc {
+ return func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ s := fn(s1)
+ if len(s) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ return &tengo.String{Value: s}, nil
+ }
+}
+
+// FuncASRSs transform a function of 'func(string) []string' signature into
+// CallableFunc type.
+func FuncASRSs(fn func(string) []string) tengo.CallableFunc {
+ return func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ res := fn(s1)
+ arr := &tengo.Array{}
+ for _, elem := range res {
+ if len(elem) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ arr.Value = append(arr.Value, &tengo.String{Value: elem})
+ }
+ return arr, nil
+ }
+}
+
+// FuncASRSE transform a function of 'func(string) (string, error)' signature
+// into CallableFunc type. User function will return 'true' if underlying
+// native function returns nil.
+func FuncASRSE(fn func(string) (string, error)) tengo.CallableFunc {
+ return func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ res, err := fn(s1)
+ if err != nil {
+ return wrapError(err), nil
+ }
+ if len(res) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ return &tengo.String{Value: res}, nil
+ }
+}
+
+// FuncASRE transform a function of 'func(string) error' signature into
+// CallableFunc type. User function will return 'true' if underlying native
+// function returns nil.
+func FuncASRE(fn func(string) error) tengo.CallableFunc {
+ return func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ return wrapError(fn(s1)), nil
+ }
+}
+
+// FuncASSRE transform a function of 'func(string, string) error' signature
+// into CallableFunc type. User function will return 'true' if underlying
+// native function returns nil.
+func FuncASSRE(fn func(string, string) error) tengo.CallableFunc {
+ return func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ return wrapError(fn(s1, s2)), nil
+ }
+}
+
+// FuncASSRSs transform a function of 'func(string, string) []string'
+// signature into CallableFunc type.
+func FuncASSRSs(fn func(string, string) []string) tengo.CallableFunc {
+ return func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ arr := &tengo.Array{}
+ for _, res := range fn(s1, s2) {
+ if len(res) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ arr.Value = append(arr.Value, &tengo.String{Value: res})
+ }
+ return arr, nil
+ }
+}
+
+// FuncASSIRSs transform a function of 'func(string, string, int) []string'
+// signature into CallableFunc type.
+func FuncASSIRSs(fn func(string, string, int) []string) tengo.CallableFunc {
+ return func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 3 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ i3, ok := tengo.ToInt(args[2])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "int(compatible)",
+ Found: args[2].TypeName(),
+ }
+ }
+ arr := &tengo.Array{}
+ for _, res := range fn(s1, s2, i3) {
+ if len(res) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ arr.Value = append(arr.Value, &tengo.String{Value: res})
+ }
+ return arr, nil
+ }
+}
+
+// FuncASSRI transform a function of 'func(string, string) int' signature into
+// CallableFunc type.
+func FuncASSRI(fn func(string, string) int) tengo.CallableFunc {
+ return func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ return &tengo.Int{Value: int64(fn(s1, s2))}, nil
+ }
+}
+
+// FuncASSRS transform a function of 'func(string, string) string' signature
+// into CallableFunc type.
+func FuncASSRS(fn func(string, string) string) tengo.CallableFunc {
+ return func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ s := fn(s1, s2)
+ if len(s) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ return &tengo.String{Value: s}, nil
+ }
+}
+
+// FuncASSRB transform a function of 'func(string, string) bool' signature
+// into CallableFunc type.
+func FuncASSRB(fn func(string, string) bool) tengo.CallableFunc {
+ return func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ if fn(s1, s2) {
+ return tengo.TrueValue, nil
+ }
+ return tengo.FalseValue, nil
+ }
+}
+
+// FuncASsSRS transform a function of 'func([]string, string) string' signature
+// into CallableFunc type.
+func FuncASsSRS(fn func([]string, string) string) tengo.CallableFunc {
+ return func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ var ss1 []string
+ switch arg0 := args[0].(type) {
+ case *tengo.Array:
+ for idx, a := range arg0.Value {
+ as, ok := tengo.ToString(a)
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: fmt.Sprintf("first[%d]", idx),
+ Expected: "string(compatible)",
+ Found: a.TypeName(),
+ }
+ }
+ ss1 = append(ss1, as)
+ }
+ case *tengo.ImmutableArray:
+ for idx, a := range arg0.Value {
+ as, ok := tengo.ToString(a)
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: fmt.Sprintf("first[%d]", idx),
+ Expected: "string(compatible)",
+ Found: a.TypeName(),
+ }
+ }
+ ss1 = append(ss1, as)
+ }
+ default:
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "array",
+ Found: args[0].TypeName(),
+ }
+ }
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ s := fn(ss1, s2)
+ if len(s) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ return &tengo.String{Value: s}, nil
+ }
+}
+
+// FuncASI64RE transform a function of 'func(string, int64) error' signature
+// into CallableFunc type.
+func FuncASI64RE(fn func(string, int64) error) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ i2, ok := tengo.ToInt64(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ return wrapError(fn(s1, i2)), nil
+ }
+}
+
+// FuncAIIRE transform a function of 'func(int, int) error' signature
+// into CallableFunc type.
+func FuncAIIRE(fn func(int, int) error) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ i1, ok := tengo.ToInt(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ return wrapError(fn(i1, i2)), nil
+ }
+}
+
+// FuncASIRS transform a function of 'func(string, int) string' signature
+// into CallableFunc type.
+func FuncASIRS(fn func(string, int) string) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ s := fn(s1, i2)
+ if len(s) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ return &tengo.String{Value: s}, nil
+ }
+}
+
+// FuncASIIRE transform a function of 'func(string, int, int) error' signature
+// into CallableFunc type.
+func FuncASIIRE(fn func(string, int, int) error) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 3 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ i3, ok := tengo.ToInt(args[2])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "int(compatible)",
+ Found: args[2].TypeName(),
+ }
+ }
+ return wrapError(fn(s1, i2, i3)), nil
+ }
+}
+
+// FuncAYRIE transform a function of 'func([]byte) (int, error)' signature
+// into CallableFunc type.
+func FuncAYRIE(fn func([]byte) (int, error)) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ y1, ok := tengo.ToByteSlice(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "bytes(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ res, err := fn(y1)
+ if err != nil {
+ return wrapError(err), nil
+ }
+ return &tengo.Int{Value: int64(res)}, nil
+ }
+}
+
+// FuncAYRS transform a function of 'func([]byte) string' signature into
+// CallableFunc type.
+func FuncAYRS(fn func([]byte) string) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ y1, ok := tengo.ToByteSlice(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "bytes(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ res := fn(y1)
+ return &tengo.String{Value: res}, nil
+ }
+}
+
+// FuncASRIE transform a function of 'func(string) (int, error)' signature
+// into CallableFunc type.
+func FuncASRIE(fn func(string) (int, error)) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ res, err := fn(s1)
+ if err != nil {
+ return wrapError(err), nil
+ }
+ return &tengo.Int{Value: int64(res)}, nil
+ }
+}
+
+// FuncASRYE transform a function of 'func(string) ([]byte, error)' signature
+// into CallableFunc type.
+func FuncASRYE(fn func(string) ([]byte, error)) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ res, err := fn(s1)
+ if err != nil {
+ return wrapError(err), nil
+ }
+ if len(res) > tengo.MaxBytesLen {
+ return nil, tengo.ErrBytesLimit
+ }
+ return &tengo.Bytes{Value: res}, nil
+ }
+}
+
+// FuncAIRSsE transform a function of 'func(int) ([]string, error)' signature
+// into CallableFunc type.
+func FuncAIRSsE(fn func(int) ([]string, error)) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ i1, ok := tengo.ToInt(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ res, err := fn(i1)
+ if err != nil {
+ return wrapError(err), nil
+ }
+ arr := &tengo.Array{}
+ for _, r := range res {
+ if len(r) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ arr.Value = append(arr.Value, &tengo.String{Value: r})
+ }
+ return arr, nil
+ }
+}
+
+// FuncAIRS transform a function of 'func(int) string' signature into
+// CallableFunc type.
+func FuncAIRS(fn func(int) string) tengo.CallableFunc {
+ return func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ i1, ok := tengo.ToInt(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ s := fn(i1)
+ if len(s) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ return &tengo.String{Value: s}, nil
+ }
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/hex.go b/vendor/github.com/d5/tengo/v2/stdlib/hex.go
new file mode 100644
index 00000000..981da696
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/hex.go
@@ -0,0 +1,12 @@
+package stdlib
+
+import (
+ "encoding/hex"
+
+ "github.com/d5/tengo/v2"
+)
+
+var hexModule = map[string]tengo.Object{
+ "encode": &tengo.UserFunction{Value: FuncAYRS(hex.EncodeToString)},
+ "decode": &tengo.UserFunction{Value: FuncASRYE(hex.DecodeString)},
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/json.go b/vendor/github.com/d5/tengo/v2/stdlib/json.go
new file mode 100644
index 00000000..be2185db
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/json.go
@@ -0,0 +1,146 @@
+package stdlib
+
+import (
+ "bytes"
+ gojson "encoding/json"
+
+ "github.com/d5/tengo/v2"
+ "github.com/d5/tengo/v2/stdlib/json"
+)
+
+var jsonModule = map[string]tengo.Object{
+ "decode": &tengo.UserFunction{
+ Name: "decode",
+ Value: jsonDecode,
+ },
+ "encode": &tengo.UserFunction{
+ Name: "encode",
+ Value: jsonEncode,
+ },
+ "indent": &tengo.UserFunction{
+ Name: "encode",
+ Value: jsonIndent,
+ },
+ "html_escape": &tengo.UserFunction{
+ Name: "html_escape",
+ Value: jsonHTMLEscape,
+ },
+}
+
+func jsonDecode(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+
+ switch o := args[0].(type) {
+ case *tengo.Bytes:
+ v, err := json.Decode(o.Value)
+ if err != nil {
+ return &tengo.Error{
+ Value: &tengo.String{Value: err.Error()},
+ }, nil
+ }
+ return v, nil
+ case *tengo.String:
+ v, err := json.Decode([]byte(o.Value))
+ if err != nil {
+ return &tengo.Error{
+ Value: &tengo.String{Value: err.Error()},
+ }, nil
+ }
+ return v, nil
+ default:
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "bytes/string",
+ Found: args[0].TypeName(),
+ }
+ }
+}
+
+func jsonEncode(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+
+ b, err := json.Encode(args[0])
+ if err != nil {
+ return &tengo.Error{Value: &tengo.String{Value: err.Error()}}, nil
+ }
+
+ return &tengo.Bytes{Value: b}, nil
+}
+
+func jsonIndent(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 3 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+
+ prefix, ok := tengo.ToString(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "prefix",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+
+ indent, ok := tengo.ToString(args[2])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "indent",
+ Expected: "string(compatible)",
+ Found: args[2].TypeName(),
+ }
+ }
+
+ switch o := args[0].(type) {
+ case *tengo.Bytes:
+ var dst bytes.Buffer
+ err := gojson.Indent(&dst, o.Value, prefix, indent)
+ if err != nil {
+ return &tengo.Error{
+ Value: &tengo.String{Value: err.Error()},
+ }, nil
+ }
+ return &tengo.Bytes{Value: dst.Bytes()}, nil
+ case *tengo.String:
+ var dst bytes.Buffer
+ err := gojson.Indent(&dst, []byte(o.Value), prefix, indent)
+ if err != nil {
+ return &tengo.Error{
+ Value: &tengo.String{Value: err.Error()},
+ }, nil
+ }
+ return &tengo.Bytes{Value: dst.Bytes()}, nil
+ default:
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "bytes/string",
+ Found: args[0].TypeName(),
+ }
+ }
+}
+
+func jsonHTMLEscape(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+
+ switch o := args[0].(type) {
+ case *tengo.Bytes:
+ var dst bytes.Buffer
+ gojson.HTMLEscape(&dst, o.Value)
+ return &tengo.Bytes{Value: dst.Bytes()}, nil
+ case *tengo.String:
+ var dst bytes.Buffer
+ gojson.HTMLEscape(&dst, []byte(o.Value))
+ return &tengo.Bytes{Value: dst.Bytes()}, nil
+ default:
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "bytes/string",
+ Found: args[0].TypeName(),
+ }
+ }
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/json/decode.go b/vendor/github.com/d5/tengo/v2/stdlib/json/decode.go
new file mode 100644
index 00000000..6d468ef0
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/json/decode.go
@@ -0,0 +1,358 @@
+// A modified version of Go's JSON implementation.
+
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import (
+ "strconv"
+ "unicode"
+ "unicode/utf16"
+ "unicode/utf8"
+
+ "github.com/d5/tengo/v2"
+)
+
+// Decode parses the JSON-encoded data and returns the result object.
+func Decode(data []byte) (tengo.Object, error) {
+ var d decodeState
+ err := checkValid(data, &d.scan)
+ if err != nil {
+ return nil, err
+ }
+ d.init(data)
+ d.scan.reset()
+ d.scanWhile(scanSkipSpace)
+ return d.value()
+}
+
+// decodeState represents the state while decoding a JSON value.
+type decodeState struct {
+ data []byte
+ off int // next read offset in data
+ opcode int // last read result
+ scan scanner
+}
+
+// readIndex returns the position of the last byte read.
+func (d *decodeState) readIndex() int {
+ return d.off - 1
+}
+
+const phasePanicMsg = "JSON decoder out of sync - data changing underfoot?"
+
+func (d *decodeState) init(data []byte) *decodeState {
+ d.data = data
+ d.off = 0
+ return d
+}
+
+// scanNext processes the byte at d.data[d.off].
+func (d *decodeState) scanNext() {
+ if d.off < len(d.data) {
+ d.opcode = d.scan.step(&d.scan, d.data[d.off])
+ d.off++
+ } else {
+ d.opcode = d.scan.eof()
+ d.off = len(d.data) + 1 // mark processed EOF with len+1
+ }
+}
+
+// scanWhile processes bytes in d.data[d.off:] until it
+// receives a scan code not equal to op.
+func (d *decodeState) scanWhile(op int) {
+ s, data, i := &d.scan, d.data, d.off
+ for i < len(data) {
+ newOp := s.step(s, data[i])
+ i++
+ if newOp != op {
+ d.opcode = newOp
+ d.off = i
+ return
+ }
+ }
+
+ d.off = len(data) + 1 // mark processed EOF with len+1
+ d.opcode = d.scan.eof()
+}
+
+func (d *decodeState) value() (tengo.Object, error) {
+ switch d.opcode {
+ default:
+ panic(phasePanicMsg)
+ case scanBeginArray:
+ o, err := d.array()
+ if err != nil {
+ return nil, err
+ }
+ d.scanNext()
+ return o, nil
+ case scanBeginObject:
+ o, err := d.object()
+ if err != nil {
+ return nil, err
+ }
+ d.scanNext()
+ return o, nil
+ case scanBeginLiteral:
+ return d.literal()
+ }
+}
+
+func (d *decodeState) array() (tengo.Object, error) {
+ var arr []tengo.Object
+ for {
+ // Look ahead for ] - can only happen on first iteration.
+ d.scanWhile(scanSkipSpace)
+ if d.opcode == scanEndArray {
+ break
+ }
+ o, err := d.value()
+ if err != nil {
+ return nil, err
+ }
+ arr = append(arr, o)
+
+ // Next token must be , or ].
+ if d.opcode == scanSkipSpace {
+ d.scanWhile(scanSkipSpace)
+ }
+ if d.opcode == scanEndArray {
+ break
+ }
+ if d.opcode != scanArrayValue {
+ panic(phasePanicMsg)
+ }
+ }
+ return &tengo.Array{Value: arr}, nil
+}
+
+func (d *decodeState) object() (tengo.Object, error) {
+ m := make(map[string]tengo.Object)
+ for {
+ // Read opening " of string key or closing }.
+ d.scanWhile(scanSkipSpace)
+ if d.opcode == scanEndObject {
+ // closing } - can only happen on first iteration.
+ break
+ }
+ if d.opcode != scanBeginLiteral {
+ panic(phasePanicMsg)
+ }
+
+ // Read string key.
+ start := d.readIndex()
+ d.scanWhile(scanContinue)
+ item := d.data[start:d.readIndex()]
+ key, ok := unquote(item)
+ if !ok {
+ panic(phasePanicMsg)
+ }
+
+ // Read : before value.
+ if d.opcode == scanSkipSpace {
+ d.scanWhile(scanSkipSpace)
+ }
+ if d.opcode != scanObjectKey {
+ panic(phasePanicMsg)
+ }
+ d.scanWhile(scanSkipSpace)
+
+ // Read value.
+ o, err := d.value()
+ if err != nil {
+ return nil, err
+ }
+
+ m[key] = o
+
+ // Next token must be , or }.
+ if d.opcode == scanSkipSpace {
+ d.scanWhile(scanSkipSpace)
+ }
+ if d.opcode == scanEndObject {
+ break
+ }
+ if d.opcode != scanObjectValue {
+ panic(phasePanicMsg)
+ }
+ }
+ return &tengo.Map{Value: m}, nil
+}
+
+func (d *decodeState) literal() (tengo.Object, error) {
+ // All bytes inside literal return scanContinue op code.
+ start := d.readIndex()
+ d.scanWhile(scanContinue)
+
+ item := d.data[start:d.readIndex()]
+
+ switch c := item[0]; c {
+ case 'n': // null
+ return tengo.UndefinedValue, nil
+
+ case 't', 'f': // true, false
+ if c == 't' {
+ return tengo.TrueValue, nil
+ }
+ return tengo.FalseValue, nil
+
+ case '"': // string
+ s, ok := unquote(item)
+ if !ok {
+ panic(phasePanicMsg)
+ }
+ return &tengo.String{Value: s}, nil
+
+ default: // number
+ if c != '-' && (c < '0' || c > '9') {
+ panic(phasePanicMsg)
+ }
+ n, _ := strconv.ParseFloat(string(item), 10)
+ return &tengo.Float{Value: n}, nil
+ }
+}
+
+// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
+// or it returns -1.
+func getu4(s []byte) rune {
+ if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
+ return -1
+ }
+ var r rune
+ for _, c := range s[2:6] {
+ switch {
+ case '0' <= c && c <= '9':
+ c = c - '0'
+ case 'a' <= c && c <= 'f':
+ c = c - 'a' + 10
+ case 'A' <= c && c <= 'F':
+ c = c - 'A' + 10
+ default:
+ return -1
+ }
+ r = r*16 + rune(c)
+ }
+ return r
+}
+
+// unquote converts a quoted JSON string literal s into an actual string t.
+// The rules are different than for Go, so cannot use strconv.Unquote.
+func unquote(s []byte) (t string, ok bool) {
+ s, ok = unquoteBytes(s)
+ t = string(s)
+ return
+}
+
+func unquoteBytes(s []byte) (t []byte, ok bool) {
+ if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
+ return
+ }
+ s = s[1 : len(s)-1]
+
+ // Check for unusual characters. If there are none, then no unquoting is
+ // needed, so return a slice of the original bytes.
+ r := 0
+ for r < len(s) {
+ c := s[r]
+ if c == '\\' || c == '"' || c < ' ' {
+ break
+ }
+ if c < utf8.RuneSelf {
+ r++
+ continue
+ }
+ rr, size := utf8.DecodeRune(s[r:])
+ if rr == utf8.RuneError && size == 1 {
+ break
+ }
+ r += size
+ }
+ if r == len(s) {
+ return s, true
+ }
+
+ b := make([]byte, len(s)+2*utf8.UTFMax)
+ w := copy(b, s[0:r])
+ for r < len(s) {
+ // Out of room? Can only happen if s is full of
+ // malformed UTF-8 and we're replacing each
+ // byte with RuneError.
+ if w >= len(b)-2*utf8.UTFMax {
+ nb := make([]byte, (len(b)+utf8.UTFMax)*2)
+ copy(nb, b[0:w])
+ b = nb
+ }
+ switch c := s[r]; {
+ case c == '\\':
+ r++
+ if r >= len(s) {
+ return
+ }
+ switch s[r] {
+ default:
+ return
+ case '"', '\\', '/', '\'':
+ b[w] = s[r]
+ r++
+ w++
+ case 'b':
+ b[w] = '\b'
+ r++
+ w++
+ case 'f':
+ b[w] = '\f'
+ r++
+ w++
+ case 'n':
+ b[w] = '\n'
+ r++
+ w++
+ case 'r':
+ b[w] = '\r'
+ r++
+ w++
+ case 't':
+ b[w] = '\t'
+ r++
+ w++
+ case 'u':
+ r--
+ rr := getu4(s[r:])
+ if rr < 0 {
+ return
+ }
+ r += 6
+ if utf16.IsSurrogate(rr) {
+ rr1 := getu4(s[r:])
+ dec := utf16.DecodeRune(rr, rr1)
+ if dec != unicode.ReplacementChar {
+ // A valid pair; consume.
+ r += 6
+ w += utf8.EncodeRune(b[w:], dec)
+ break
+ }
+ // Invalid surrogate; fall back to replacement rune.
+ rr = unicode.ReplacementChar
+ }
+ w += utf8.EncodeRune(b[w:], rr)
+ }
+ // Quote, control characters are invalid.
+ case c == '"', c < ' ':
+ return
+ // ASCII
+ case c < utf8.RuneSelf:
+ b[w] = c
+ r++
+ w++
+ // Coerce to well-formed UTF-8.
+ default:
+ rr, size := utf8.DecodeRune(s[r:])
+ r += size
+ w += utf8.EncodeRune(b[w:], rr)
+ }
+ }
+ return b[0:w], true
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/json/encode.go b/vendor/github.com/d5/tengo/v2/stdlib/json/encode.go
new file mode 100644
index 00000000..ab7ca6ff
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/json/encode.go
@@ -0,0 +1,146 @@
+// A modified version of Go's JSON implementation.
+
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import (
+ "encoding/base64"
+ "errors"
+ "math"
+ "strconv"
+
+ "github.com/d5/tengo/v2"
+)
+
+// Encode returns the JSON encoding of the object.
+func Encode(o tengo.Object) ([]byte, error) {
+ var b []byte
+
+ switch o := o.(type) {
+ case *tengo.Array:
+ b = append(b, '[')
+ len1 := len(o.Value) - 1
+ for idx, elem := range o.Value {
+ eb, err := Encode(elem)
+ if err != nil {
+ return nil, err
+ }
+ b = append(b, eb...)
+ if idx < len1 {
+ b = append(b, ',')
+ }
+ }
+ b = append(b, ']')
+ case *tengo.ImmutableArray:
+ b = append(b, '[')
+ len1 := len(o.Value) - 1
+ for idx, elem := range o.Value {
+ eb, err := Encode(elem)
+ if err != nil {
+ return nil, err
+ }
+ b = append(b, eb...)
+ if idx < len1 {
+ b = append(b, ',')
+ }
+ }
+ b = append(b, ']')
+ case *tengo.Map:
+ b = append(b, '{')
+ len1 := len(o.Value) - 1
+ idx := 0
+ for key, value := range o.Value {
+ b = strconv.AppendQuote(b, key)
+ b = append(b, ':')
+ eb, err := Encode(value)
+ if err != nil {
+ return nil, err
+ }
+ b = append(b, eb...)
+ if idx < len1 {
+ b = append(b, ',')
+ }
+ idx++
+ }
+ b = append(b, '}')
+ case *tengo.ImmutableMap:
+ b = append(b, '{')
+ len1 := len(o.Value) - 1
+ idx := 0
+ for key, value := range o.Value {
+ b = strconv.AppendQuote(b, key)
+ b = append(b, ':')
+ eb, err := Encode(value)
+ if err != nil {
+ return nil, err
+ }
+ b = append(b, eb...)
+ if idx < len1 {
+ b = append(b, ',')
+ }
+ idx++
+ }
+ b = append(b, '}')
+ case *tengo.Bool:
+ if o.IsFalsy() {
+ b = strconv.AppendBool(b, false)
+ } else {
+ b = strconv.AppendBool(b, true)
+ }
+ case *tengo.Bytes:
+ b = append(b, '"')
+ encodedLen := base64.StdEncoding.EncodedLen(len(o.Value))
+ dst := make([]byte, encodedLen)
+ base64.StdEncoding.Encode(dst, o.Value)
+ b = append(b, dst...)
+ b = append(b, '"')
+ case *tengo.Char:
+ b = strconv.AppendInt(b, int64(o.Value), 10)
+ case *tengo.Float:
+ var y []byte
+
+ f := o.Value
+ if math.IsInf(f, 0) || math.IsNaN(f) {
+ return nil, errors.New("unsupported float value")
+ }
+
+ // Convert as if by ES6 number to string conversion.
+ // This matches most other JSON generators.
+ abs := math.Abs(f)
+ fmt := byte('f')
+ if abs != 0 {
+ if abs < 1e-6 || abs >= 1e21 {
+ fmt = 'e'
+ }
+ }
+ y = strconv.AppendFloat(y, f, fmt, -1, 64)
+ if fmt == 'e' {
+ // clean up e-09 to e-9
+ n := len(y)
+ if n >= 4 && y[n-4] == 'e' && y[n-3] == '-' && y[n-2] == '0' {
+ y[n-2] = y[n-1]
+ y = y[:n-1]
+ }
+ }
+
+ b = append(b, y...)
+ case *tengo.Int:
+ b = strconv.AppendInt(b, o.Value, 10)
+ case *tengo.String:
+ b = strconv.AppendQuote(b, o.Value)
+ case *tengo.Time:
+ y, err := o.Value.MarshalJSON()
+ if err != nil {
+ return nil, err
+ }
+ b = append(b, y...)
+ case *tengo.Undefined:
+ b = append(b, "null"...)
+ default:
+ // unknown type: ignore
+ }
+ return b, nil
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/json/scanner.go b/vendor/github.com/d5/tengo/v2/stdlib/json/scanner.go
new file mode 100644
index 00000000..aed15cf5
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/json/scanner.go
@@ -0,0 +1,562 @@
+// A modified version of Go's JSON implementation.
+
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import "strconv"
+
+func checkValid(data []byte, scan *scanner) error {
+ scan.reset()
+ for _, c := range data {
+ scan.bytes++
+ if scan.step(scan, c) == scanError {
+ return scan.err
+ }
+ }
+ if scan.eof() == scanError {
+ return scan.err
+ }
+ return nil
+}
+
+// A SyntaxError is a description of a JSON syntax error.
+type SyntaxError struct {
+ msg string // description of error
+ Offset int64 // error occurred after reading Offset bytes
+}
+
+func (e *SyntaxError) Error() string { return e.msg }
+
+// A scanner is a JSON scanning state machine.
+// Callers call scan.reset() and then pass bytes in one at a time
+// by calling scan.step(&scan, c) for each byte.
+// The return value, referred to as an opcode, tells the
+// caller about significant parsing events like beginning
+// and ending literals, objects, and arrays, so that the
+// caller can follow along if it wishes.
+// The return value scanEnd indicates that a single top-level
+// JSON value has been completed, *before* the byte that
+// just got passed in. (The indication must be delayed in order
+// to recognize the end of numbers: is 123 a whole value or
+// the beginning of 12345e+6?).
+type scanner struct {
+ // The step is a func to be called to execute the next transition.
+ // Also tried using an integer constant and a single func
+ // with a switch, but using the func directly was 10% faster
+ // on a 64-bit Mac Mini, and it's nicer to read.
+ step func(*scanner, byte) int
+
+ // Reached end of top-level value.
+ endTop bool
+
+ // Stack of what we're in the middle of - array values, object keys, object values.
+ parseState []int
+
+ // Error that happened, if any.
+ err error
+
+ // total bytes consumed, updated by decoder.Decode
+ bytes int64
+}
+
+// These values are returned by the state transition functions
+// assigned to scanner.state and the method scanner.eof.
+// They give details about the current state of the scan that
+// callers might be interested to know about.
+// It is okay to ignore the return value of any particular
+// call to scanner.state: if one call returns scanError,
+// every subsequent call will return scanError too.
+const (
+ // Continue.
+ scanContinue = iota // uninteresting byte
+ scanBeginLiteral // end implied by next result != scanContinue
+ scanBeginObject // begin object
+ scanObjectKey // just finished object key (string)
+ scanObjectValue // just finished non-last object value
+ scanEndObject // end object (implies scanObjectValue if possible)
+ scanBeginArray // begin array
+ scanArrayValue // just finished array value
+ scanEndArray // end array (implies scanArrayValue if possible)
+ scanSkipSpace // space byte; can skip; known to be last "continue" result
+
+ // Stop.
+ scanEnd // top-level value ended *before* this byte; known to be first "stop" result
+ scanError // hit an error, scanner.err.
+)
+
+// These values are stored in the parseState stack.
+// They give the current state of a composite value
+// being scanned. If the parser is inside a nested value
+// the parseState describes the nested state, outermost at entry 0.
+const (
+ parseObjectKey = iota // parsing object key (before colon)
+ parseObjectValue // parsing object value (after colon)
+ parseArrayValue // parsing array value
+)
+
+// reset prepares the scanner for use.
+// It must be called before calling s.step.
+func (s *scanner) reset() {
+ s.step = stateBeginValue
+ s.parseState = s.parseState[0:0]
+ s.err = nil
+ s.endTop = false
+}
+
+// eof tells the scanner that the end of input has been reached.
+// It returns a scan status just as s.step does.
+func (s *scanner) eof() int {
+ if s.err != nil {
+ return scanError
+ }
+ if s.endTop {
+ return scanEnd
+ }
+ s.step(s, ' ')
+ if s.endTop {
+ return scanEnd
+ }
+ if s.err == nil {
+ s.err = &SyntaxError{"unexpected end of JSON input", s.bytes}
+ }
+ return scanError
+}
+
+// pushParseState pushes a new parse state p onto the parse stack.
+func (s *scanner) pushParseState(p int) {
+ s.parseState = append(s.parseState, p)
+}
+
+// popParseState pops a parse state (already obtained) off the stack
+// and updates s.step accordingly.
+func (s *scanner) popParseState() {
+ n := len(s.parseState) - 1
+ s.parseState = s.parseState[0:n]
+ if n == 0 {
+ s.step = stateEndTop
+ s.endTop = true
+ } else {
+ s.step = stateEndValue
+ }
+}
+
+func isSpace(c byte) bool {
+ return c == ' ' || c == '\t' || c == '\r' || c == '\n'
+}
+
+// stateBeginValueOrEmpty is the state after reading `[`.
+func stateBeginValueOrEmpty(s *scanner, c byte) int {
+ if c <= ' ' && isSpace(c) {
+ return scanSkipSpace
+ }
+ if c == ']' {
+ return stateEndValue(s, c)
+ }
+ return stateBeginValue(s, c)
+}
+
+// stateBeginValue is the state at the beginning of the input.
+func stateBeginValue(s *scanner, c byte) int {
+ if c <= ' ' && isSpace(c) {
+ return scanSkipSpace
+ }
+ switch c {
+ case '{':
+ s.step = stateBeginStringOrEmpty
+ s.pushParseState(parseObjectKey)
+ return scanBeginObject
+ case '[':
+ s.step = stateBeginValueOrEmpty
+ s.pushParseState(parseArrayValue)
+ return scanBeginArray
+ case '"':
+ s.step = stateInString
+ return scanBeginLiteral
+ case '-':
+ s.step = stateNeg
+ return scanBeginLiteral
+ case '0': // beginning of 0.123
+ s.step = state0
+ return scanBeginLiteral
+ case 't': // beginning of true
+ s.step = stateT
+ return scanBeginLiteral
+ case 'f': // beginning of false
+ s.step = stateF
+ return scanBeginLiteral
+ case 'n': // beginning of null
+ s.step = stateN
+ return scanBeginLiteral
+ }
+ if '1' <= c && c <= '9' { // beginning of 1234.5
+ s.step = state1
+ return scanBeginLiteral
+ }
+ return s.error(c, "looking for beginning of value")
+}
+
+// stateBeginStringOrEmpty is the state after reading `{`.
+func stateBeginStringOrEmpty(s *scanner, c byte) int {
+ if c <= ' ' && isSpace(c) {
+ return scanSkipSpace
+ }
+ if c == '}' {
+ n := len(s.parseState)
+ s.parseState[n-1] = parseObjectValue
+ return stateEndValue(s, c)
+ }
+ return stateBeginString(s, c)
+}
+
+// stateBeginString is the state after reading `{"key": value,`.
+func stateBeginString(s *scanner, c byte) int {
+ if c <= ' ' && isSpace(c) {
+ return scanSkipSpace
+ }
+ if c == '"' {
+ s.step = stateInString
+ return scanBeginLiteral
+ }
+ return s.error(c, "looking for beginning of object key string")
+}
+
+// stateEndValue is the state after completing a value,
+// such as after reading `{}` or `true` or `["x"`.
+func stateEndValue(s *scanner, c byte) int {
+ n := len(s.parseState)
+ if n == 0 {
+ // Completed top-level before the current byte.
+ s.step = stateEndTop
+ s.endTop = true
+ return stateEndTop(s, c)
+ }
+ if c <= ' ' && isSpace(c) {
+ s.step = stateEndValue
+ return scanSkipSpace
+ }
+ ps := s.parseState[n-1]
+ switch ps {
+ case parseObjectKey:
+ if c == ':' {
+ s.parseState[n-1] = parseObjectValue
+ s.step = stateBeginValue
+ return scanObjectKey
+ }
+ return s.error(c, "after object key")
+ case parseObjectValue:
+ if c == ',' {
+ s.parseState[n-1] = parseObjectKey
+ s.step = stateBeginString
+ return scanObjectValue
+ }
+ if c == '}' {
+ s.popParseState()
+ return scanEndObject
+ }
+ return s.error(c, "after object key:value pair")
+ case parseArrayValue:
+ if c == ',' {
+ s.step = stateBeginValue
+ return scanArrayValue
+ }
+ if c == ']' {
+ s.popParseState()
+ return scanEndArray
+ }
+ return s.error(c, "after array element")
+ }
+ return s.error(c, "")
+}
+
+// stateEndTop is the state after finishing the top-level value,
+// such as after reading `{}` or `[1,2,3]`.
+// Only space characters should be seen now.
+func stateEndTop(s *scanner, c byte) int {
+ if !isSpace(c) {
+ // Complain about non-space byte on next call.
+ s.error(c, "after top-level value")
+ }
+ return scanEnd
+}
+
+// stateInString is the state after reading `"`.
+func stateInString(s *scanner, c byte) int {
+ if c == '"' {
+ s.step = stateEndValue
+ return scanContinue
+ }
+ if c == '\\' {
+ s.step = stateInStringEsc
+ return scanContinue
+ }
+ if c < 0x20 {
+ return s.error(c, "in string literal")
+ }
+ return scanContinue
+}
+
+// stateInStringEsc is the state after reading `"\` during a quoted string.
+func stateInStringEsc(s *scanner, c byte) int {
+ switch c {
+ case 'b', 'f', 'n', 'r', 't', '\\', '/', '"':
+ s.step = stateInString
+ return scanContinue
+ case 'u':
+ s.step = stateInStringEscU
+ return scanContinue
+ }
+ return s.error(c, "in string escape code")
+}
+
+// stateInStringEscU is the state after reading `"\u` during a quoted string.
+func stateInStringEscU(s *scanner, c byte) int {
+ if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
+ s.step = stateInStringEscU1
+ return scanContinue
+ }
+ // numbers
+ return s.error(c, "in \\u hexadecimal character escape")
+}
+
+// stateInStringEscU1 is the state after reading `"\u1` during a quoted string.
+func stateInStringEscU1(s *scanner, c byte) int {
+ if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
+ s.step = stateInStringEscU12
+ return scanContinue
+ }
+ // numbers
+ return s.error(c, "in \\u hexadecimal character escape")
+}
+
+// stateInStringEscU12 is the state after reading `"\u12` during a quoted string.
+func stateInStringEscU12(s *scanner, c byte) int {
+ if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
+ s.step = stateInStringEscU123
+ return scanContinue
+ }
+ // numbers
+ return s.error(c, "in \\u hexadecimal character escape")
+}
+
+// stateInStringEscU123 is the state after reading `"\u123` during a quoted string.
+func stateInStringEscU123(s *scanner, c byte) int {
+ if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
+ s.step = stateInString
+ return scanContinue
+ }
+ // numbers
+ return s.error(c, "in \\u hexadecimal character escape")
+}
+
+// stateNeg is the state after reading `-` during a number.
+func stateNeg(s *scanner, c byte) int {
+ if c == '0' {
+ s.step = state0
+ return scanContinue
+ }
+ if '1' <= c && c <= '9' {
+ s.step = state1
+ return scanContinue
+ }
+ return s.error(c, "in numeric literal")
+}
+
+// state1 is the state after reading a non-zero integer during a number,
+// such as after reading `1` or `100` but not `0`.
+func state1(s *scanner, c byte) int {
+ if '0' <= c && c <= '9' {
+ s.step = state1
+ return scanContinue
+ }
+ return state0(s, c)
+}
+
+// state0 is the state after reading `0` during a number.
+func state0(s *scanner, c byte) int {
+ if c == '.' {
+ s.step = stateDot
+ return scanContinue
+ }
+ if c == 'e' || c == 'E' {
+ s.step = stateE
+ return scanContinue
+ }
+ return stateEndValue(s, c)
+}
+
+// stateDot is the state after reading the integer and decimal point in a number,
+// such as after reading `1.`.
+func stateDot(s *scanner, c byte) int {
+ if '0' <= c && c <= '9' {
+ s.step = stateDot0
+ return scanContinue
+ }
+ return s.error(c, "after decimal point in numeric literal")
+}
+
+// stateDot0 is the state after reading the integer, decimal point, and subsequent
+// digits of a number, such as after reading `3.14`.
+func stateDot0(s *scanner, c byte) int {
+ if '0' <= c && c <= '9' {
+ return scanContinue
+ }
+ if c == 'e' || c == 'E' {
+ s.step = stateE
+ return scanContinue
+ }
+ return stateEndValue(s, c)
+}
+
+// stateE is the state after reading the mantissa and e in a number,
+// such as after reading `314e` or `0.314e`.
+func stateE(s *scanner, c byte) int {
+ if c == '+' || c == '-' {
+ s.step = stateESign
+ return scanContinue
+ }
+ return stateESign(s, c)
+}
+
+// stateESign is the state after reading the mantissa, e, and sign in a number,
+// such as after reading `314e-` or `0.314e+`.
+func stateESign(s *scanner, c byte) int {
+ if '0' <= c && c <= '9' {
+ s.step = stateE0
+ return scanContinue
+ }
+ return s.error(c, "in exponent of numeric literal")
+}
+
+// stateE0 is the state after reading the mantissa, e, optional sign,
+// and at least one digit of the exponent in a number,
+// such as after reading `314e-2` or `0.314e+1` or `3.14e0`.
+func stateE0(s *scanner, c byte) int {
+ if '0' <= c && c <= '9' {
+ return scanContinue
+ }
+ return stateEndValue(s, c)
+}
+
+// stateT is the state after reading `t`.
+func stateT(s *scanner, c byte) int {
+ if c == 'r' {
+ s.step = stateTr
+ return scanContinue
+ }
+ return s.error(c, "in literal true (expecting 'r')")
+}
+
+// stateTr is the state after reading `tr`.
+func stateTr(s *scanner, c byte) int {
+ if c == 'u' {
+ s.step = stateTru
+ return scanContinue
+ }
+ return s.error(c, "in literal true (expecting 'u')")
+}
+
+// stateTru is the state after reading `tru`.
+func stateTru(s *scanner, c byte) int {
+ if c == 'e' {
+ s.step = stateEndValue
+ return scanContinue
+ }
+ return s.error(c, "in literal true (expecting 'e')")
+}
+
+// stateF is the state after reading `f`.
+func stateF(s *scanner, c byte) int {
+ if c == 'a' {
+ s.step = stateFa
+ return scanContinue
+ }
+ return s.error(c, "in literal false (expecting 'a')")
+}
+
+// stateFa is the state after reading `fa`.
+func stateFa(s *scanner, c byte) int {
+ if c == 'l' {
+ s.step = stateFal
+ return scanContinue
+ }
+ return s.error(c, "in literal false (expecting 'l')")
+}
+
+// stateFal is the state after reading `fal`.
+func stateFal(s *scanner, c byte) int {
+ if c == 's' {
+ s.step = stateFals
+ return scanContinue
+ }
+ return s.error(c, "in literal false (expecting 's')")
+}
+
+// stateFals is the state after reading `fals`.
+func stateFals(s *scanner, c byte) int {
+ if c == 'e' {
+ s.step = stateEndValue
+ return scanContinue
+ }
+ return s.error(c, "in literal false (expecting 'e')")
+}
+
+// stateN is the state after reading `n`.
+func stateN(s *scanner, c byte) int {
+ if c == 'u' {
+ s.step = stateNu
+ return scanContinue
+ }
+ return s.error(c, "in literal null (expecting 'u')")
+}
+
+// stateNu is the state after reading `nu`.
+func stateNu(s *scanner, c byte) int {
+ if c == 'l' {
+ s.step = stateNul
+ return scanContinue
+ }
+ return s.error(c, "in literal null (expecting 'l')")
+}
+
+// stateNul is the state after reading `nul`.
+func stateNul(s *scanner, c byte) int {
+ if c == 'l' {
+ s.step = stateEndValue
+ return scanContinue
+ }
+ return s.error(c, "in literal null (expecting 'l')")
+}
+
+// stateError is the state after reaching a syntax error,
+// such as after reading `[1}` or `5.1.2`.
+func stateError(_ *scanner, _ byte) int {
+ return scanError
+}
+
+// error records an error and switches to the error state.
+func (s *scanner) error(c byte, context string) int {
+ s.step = stateError
+ s.err = &SyntaxError{
+ msg: "invalid character " + quoteChar(c) + " " + context,
+ Offset: s.bytes,
+ }
+ return scanError
+}
+
+// quoteChar formats c as a quoted character literal
+func quoteChar(c byte) string {
+ // special cases - different from quoted strings
+ if c == '\'' {
+ return `'\''`
+ }
+ if c == '"' {
+ return `'"'`
+ }
+
+ // use quoted string with different quotation marks
+ s := strconv.Quote(string(c))
+ return "'" + s[1:len(s)-1] + "'"
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/math.go b/vendor/github.com/d5/tengo/v2/stdlib/math.go
new file mode 100644
index 00000000..633ea09f
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/math.go
@@ -0,0 +1,233 @@
+package stdlib
+
+import (
+ "math"
+
+ "github.com/d5/tengo/v2"
+)
+
+var mathModule = map[string]tengo.Object{
+ "e": &tengo.Float{Value: math.E},
+ "pi": &tengo.Float{Value: math.Pi},
+ "phi": &tengo.Float{Value: math.Phi},
+ "sqrt2": &tengo.Float{Value: math.Sqrt2},
+ "sqrtE": &tengo.Float{Value: math.SqrtE},
+ "sqrtPi": &tengo.Float{Value: math.SqrtPi},
+ "sqrtPhi": &tengo.Float{Value: math.SqrtPhi},
+ "ln2": &tengo.Float{Value: math.Ln2},
+ "log2E": &tengo.Float{Value: math.Log2E},
+ "ln10": &tengo.Float{Value: math.Ln10},
+ "log10E": &tengo.Float{Value: math.Log10E},
+ "abs": &tengo.UserFunction{
+ Name: "abs",
+ Value: FuncAFRF(math.Abs),
+ },
+ "acos": &tengo.UserFunction{
+ Name: "acos",
+ Value: FuncAFRF(math.Acos),
+ },
+ "acosh": &tengo.UserFunction{
+ Name: "acosh",
+ Value: FuncAFRF(math.Acosh),
+ },
+ "asin": &tengo.UserFunction{
+ Name: "asin",
+ Value: FuncAFRF(math.Asin),
+ },
+ "asinh": &tengo.UserFunction{
+ Name: "asinh",
+ Value: FuncAFRF(math.Asinh),
+ },
+ "atan": &tengo.UserFunction{
+ Name: "atan",
+ Value: FuncAFRF(math.Atan),
+ },
+ "atan2": &tengo.UserFunction{
+ Name: "atan2",
+ Value: FuncAFFRF(math.Atan2),
+ },
+ "atanh": &tengo.UserFunction{
+ Name: "atanh",
+ Value: FuncAFRF(math.Atanh),
+ },
+ "cbrt": &tengo.UserFunction{
+ Name: "cbrt",
+ Value: FuncAFRF(math.Cbrt),
+ },
+ "ceil": &tengo.UserFunction{
+ Name: "ceil",
+ Value: FuncAFRF(math.Ceil),
+ },
+ "copysign": &tengo.UserFunction{
+ Name: "copysign",
+ Value: FuncAFFRF(math.Copysign),
+ },
+ "cos": &tengo.UserFunction{
+ Name: "cos",
+ Value: FuncAFRF(math.Cos),
+ },
+ "cosh": &tengo.UserFunction{
+ Name: "cosh",
+ Value: FuncAFRF(math.Cosh),
+ },
+ "dim": &tengo.UserFunction{
+ Name: "dim",
+ Value: FuncAFFRF(math.Dim),
+ },
+ "erf": &tengo.UserFunction{
+ Name: "erf",
+ Value: FuncAFRF(math.Erf),
+ },
+ "erfc": &tengo.UserFunction{
+ Name: "erfc",
+ Value: FuncAFRF(math.Erfc),
+ },
+ "exp": &tengo.UserFunction{
+ Name: "exp",
+ Value: FuncAFRF(math.Exp),
+ },
+ "exp2": &tengo.UserFunction{
+ Name: "exp2",
+ Value: FuncAFRF(math.Exp2),
+ },
+ "expm1": &tengo.UserFunction{
+ Name: "expm1",
+ Value: FuncAFRF(math.Expm1),
+ },
+ "floor": &tengo.UserFunction{
+ Name: "floor",
+ Value: FuncAFRF(math.Floor),
+ },
+ "gamma": &tengo.UserFunction{
+ Name: "gamma",
+ Value: FuncAFRF(math.Gamma),
+ },
+ "hypot": &tengo.UserFunction{
+ Name: "hypot",
+ Value: FuncAFFRF(math.Hypot),
+ },
+ "ilogb": &tengo.UserFunction{
+ Name: "ilogb",
+ Value: FuncAFRI(math.Ilogb),
+ },
+ "inf": &tengo.UserFunction{
+ Name: "inf",
+ Value: FuncAIRF(math.Inf),
+ },
+ "is_inf": &tengo.UserFunction{
+ Name: "is_inf",
+ Value: FuncAFIRB(math.IsInf),
+ },
+ "is_nan": &tengo.UserFunction{
+ Name: "is_nan",
+ Value: FuncAFRB(math.IsNaN),
+ },
+ "j0": &tengo.UserFunction{
+ Name: "j0",
+ Value: FuncAFRF(math.J0),
+ },
+ "j1": &tengo.UserFunction{
+ Name: "j1",
+ Value: FuncAFRF(math.J1),
+ },
+ "jn": &tengo.UserFunction{
+ Name: "jn",
+ Value: FuncAIFRF(math.Jn),
+ },
+ "ldexp": &tengo.UserFunction{
+ Name: "ldexp",
+ Value: FuncAFIRF(math.Ldexp),
+ },
+ "log": &tengo.UserFunction{
+ Name: "log",
+ Value: FuncAFRF(math.Log),
+ },
+ "log10": &tengo.UserFunction{
+ Name: "log10",
+ Value: FuncAFRF(math.Log10),
+ },
+ "log1p": &tengo.UserFunction{
+ Name: "log1p",
+ Value: FuncAFRF(math.Log1p),
+ },
+ "log2": &tengo.UserFunction{
+ Name: "log2",
+ Value: FuncAFRF(math.Log2),
+ },
+ "logb": &tengo.UserFunction{
+ Name: "logb",
+ Value: FuncAFRF(math.Logb),
+ },
+ "max": &tengo.UserFunction{
+ Name: "max",
+ Value: FuncAFFRF(math.Max),
+ },
+ "min": &tengo.UserFunction{
+ Name: "min",
+ Value: FuncAFFRF(math.Min),
+ },
+ "mod": &tengo.UserFunction{
+ Name: "mod",
+ Value: FuncAFFRF(math.Mod),
+ },
+ "nan": &tengo.UserFunction{
+ Name: "nan",
+ Value: FuncARF(math.NaN),
+ },
+ "nextafter": &tengo.UserFunction{
+ Name: "nextafter",
+ Value: FuncAFFRF(math.Nextafter),
+ },
+ "pow": &tengo.UserFunction{
+ Name: "pow",
+ Value: FuncAFFRF(math.Pow),
+ },
+ "pow10": &tengo.UserFunction{
+ Name: "pow10",
+ Value: FuncAIRF(math.Pow10),
+ },
+ "remainder": &tengo.UserFunction{
+ Name: "remainder",
+ Value: FuncAFFRF(math.Remainder),
+ },
+ "signbit": &tengo.UserFunction{
+ Name: "signbit",
+ Value: FuncAFRB(math.Signbit),
+ },
+ "sin": &tengo.UserFunction{
+ Name: "sin",
+ Value: FuncAFRF(math.Sin),
+ },
+ "sinh": &tengo.UserFunction{
+ Name: "sinh",
+ Value: FuncAFRF(math.Sinh),
+ },
+ "sqrt": &tengo.UserFunction{
+ Name: "sqrt",
+ Value: FuncAFRF(math.Sqrt),
+ },
+ "tan": &tengo.UserFunction{
+ Name: "tan",
+ Value: FuncAFRF(math.Tan),
+ },
+ "tanh": &tengo.UserFunction{
+ Name: "tanh",
+ Value: FuncAFRF(math.Tanh),
+ },
+ "trunc": &tengo.UserFunction{
+ Name: "trunc",
+ Value: FuncAFRF(math.Trunc),
+ },
+ "y0": &tengo.UserFunction{
+ Name: "y0",
+ Value: FuncAFRF(math.Y0),
+ },
+ "y1": &tengo.UserFunction{
+ Name: "y1",
+ Value: FuncAFRF(math.Y1),
+ },
+ "yn": &tengo.UserFunction{
+ Name: "yn",
+ Value: FuncAIFRF(math.Yn),
+ },
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/os.go b/vendor/github.com/d5/tengo/v2/stdlib/os.go
new file mode 100644
index 00000000..576bc94b
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/os.go
@@ -0,0 +1,564 @@
+package stdlib
+
+import (
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/exec"
+
+ "github.com/d5/tengo/v2"
+)
+
+var osModule = map[string]tengo.Object{
+ "o_rdonly": &tengo.Int{Value: int64(os.O_RDONLY)},
+ "o_wronly": &tengo.Int{Value: int64(os.O_WRONLY)},
+ "o_rdwr": &tengo.Int{Value: int64(os.O_RDWR)},
+ "o_append": &tengo.Int{Value: int64(os.O_APPEND)},
+ "o_create": &tengo.Int{Value: int64(os.O_CREATE)},
+ "o_excl": &tengo.Int{Value: int64(os.O_EXCL)},
+ "o_sync": &tengo.Int{Value: int64(os.O_SYNC)},
+ "o_trunc": &tengo.Int{Value: int64(os.O_TRUNC)},
+ "mode_dir": &tengo.Int{Value: int64(os.ModeDir)},
+ "mode_append": &tengo.Int{Value: int64(os.ModeAppend)},
+ "mode_exclusive": &tengo.Int{Value: int64(os.ModeExclusive)},
+ "mode_temporary": &tengo.Int{Value: int64(os.ModeTemporary)},
+ "mode_symlink": &tengo.Int{Value: int64(os.ModeSymlink)},
+ "mode_device": &tengo.Int{Value: int64(os.ModeDevice)},
+ "mode_named_pipe": &tengo.Int{Value: int64(os.ModeNamedPipe)},
+ "mode_socket": &tengo.Int{Value: int64(os.ModeSocket)},
+ "mode_setuid": &tengo.Int{Value: int64(os.ModeSetuid)},
+ "mode_setgui": &tengo.Int{Value: int64(os.ModeSetgid)},
+ "mode_char_device": &tengo.Int{Value: int64(os.ModeCharDevice)},
+ "mode_sticky": &tengo.Int{Value: int64(os.ModeSticky)},
+ "mode_type": &tengo.Int{Value: int64(os.ModeType)},
+ "mode_perm": &tengo.Int{Value: int64(os.ModePerm)},
+ "path_separator": &tengo.Char{Value: os.PathSeparator},
+ "path_list_separator": &tengo.Char{Value: os.PathListSeparator},
+ "dev_null": &tengo.String{Value: os.DevNull},
+ "seek_set": &tengo.Int{Value: int64(io.SeekStart)},
+ "seek_cur": &tengo.Int{Value: int64(io.SeekCurrent)},
+ "seek_end": &tengo.Int{Value: int64(io.SeekEnd)},
+ "args": &tengo.UserFunction{
+ Name: "args",
+ Value: osArgs,
+ }, // args() => array(string)
+ "chdir": &tengo.UserFunction{
+ Name: "chdir",
+ Value: FuncASRE(os.Chdir),
+ }, // chdir(dir string) => error
+ "chmod": osFuncASFmRE("chmod", os.Chmod), // chmod(name string, mode int) => error
+ "chown": &tengo.UserFunction{
+ Name: "chown",
+ Value: FuncASIIRE(os.Chown),
+ }, // chown(name string, uid int, gid int) => error
+ "clearenv": &tengo.UserFunction{
+ Name: "clearenv",
+ Value: FuncAR(os.Clearenv),
+ }, // clearenv()
+ "environ": &tengo.UserFunction{
+ Name: "environ",
+ Value: FuncARSs(os.Environ),
+ }, // environ() => array(string)
+ "exit": &tengo.UserFunction{
+ Name: "exit",
+ Value: FuncAIR(os.Exit),
+ }, // exit(code int)
+ "expand_env": &tengo.UserFunction{
+ Name: "expand_env",
+ Value: osExpandEnv,
+ }, // expand_env(s string) => string
+ "getegid": &tengo.UserFunction{
+ Name: "getegid",
+ Value: FuncARI(os.Getegid),
+ }, // getegid() => int
+ "getenv": &tengo.UserFunction{
+ Name: "getenv",
+ Value: FuncASRS(os.Getenv),
+ }, // getenv(s string) => string
+ "geteuid": &tengo.UserFunction{
+ Name: "geteuid",
+ Value: FuncARI(os.Geteuid),
+ }, // geteuid() => int
+ "getgid": &tengo.UserFunction{
+ Name: "getgid",
+ Value: FuncARI(os.Getgid),
+ }, // getgid() => int
+ "getgroups": &tengo.UserFunction{
+ Name: "getgroups",
+ Value: FuncARIsE(os.Getgroups),
+ }, // getgroups() => array(string)/error
+ "getpagesize": &tengo.UserFunction{
+ Name: "getpagesize",
+ Value: FuncARI(os.Getpagesize),
+ }, // getpagesize() => int
+ "getpid": &tengo.UserFunction{
+ Name: "getpid",
+ Value: FuncARI(os.Getpid),
+ }, // getpid() => int
+ "getppid": &tengo.UserFunction{
+ Name: "getppid",
+ Value: FuncARI(os.Getppid),
+ }, // getppid() => int
+ "getuid": &tengo.UserFunction{
+ Name: "getuid",
+ Value: FuncARI(os.Getuid),
+ }, // getuid() => int
+ "getwd": &tengo.UserFunction{
+ Name: "getwd",
+ Value: FuncARSE(os.Getwd),
+ }, // getwd() => string/error
+ "hostname": &tengo.UserFunction{
+ Name: "hostname",
+ Value: FuncARSE(os.Hostname),
+ }, // hostname() => string/error
+ "lchown": &tengo.UserFunction{
+ Name: "lchown",
+ Value: FuncASIIRE(os.Lchown),
+ }, // lchown(name string, uid int, gid int) => error
+ "link": &tengo.UserFunction{
+ Name: "link",
+ Value: FuncASSRE(os.Link),
+ }, // link(oldname string, newname string) => error
+ "lookup_env": &tengo.UserFunction{
+ Name: "lookup_env",
+ Value: osLookupEnv,
+ }, // lookup_env(key string) => string/false
+ "mkdir": osFuncASFmRE("mkdir", os.Mkdir), // mkdir(name string, perm int) => error
+ "mkdir_all": osFuncASFmRE("mkdir_all", os.MkdirAll), // mkdir_all(name string, perm int) => error
+ "readlink": &tengo.UserFunction{
+ Name: "readlink",
+ Value: FuncASRSE(os.Readlink),
+ }, // readlink(name string) => string/error
+ "remove": &tengo.UserFunction{
+ Name: "remove",
+ Value: FuncASRE(os.Remove),
+ }, // remove(name string) => error
+ "remove_all": &tengo.UserFunction{
+ Name: "remove_all",
+ Value: FuncASRE(os.RemoveAll),
+ }, // remove_all(name string) => error
+ "rename": &tengo.UserFunction{
+ Name: "rename",
+ Value: FuncASSRE(os.Rename),
+ }, // rename(oldpath string, newpath string) => error
+ "setenv": &tengo.UserFunction{
+ Name: "setenv",
+ Value: FuncASSRE(os.Setenv),
+ }, // setenv(key string, value string) => error
+ "symlink": &tengo.UserFunction{
+ Name: "symlink",
+ Value: FuncASSRE(os.Symlink),
+ }, // symlink(oldname string newname string) => error
+ "temp_dir": &tengo.UserFunction{
+ Name: "temp_dir",
+ Value: FuncARS(os.TempDir),
+ }, // temp_dir() => string
+ "truncate": &tengo.UserFunction{
+ Name: "truncate",
+ Value: FuncASI64RE(os.Truncate),
+ }, // truncate(name string, size int) => error
+ "unsetenv": &tengo.UserFunction{
+ Name: "unsetenv",
+ Value: FuncASRE(os.Unsetenv),
+ }, // unsetenv(key string) => error
+ "create": &tengo.UserFunction{
+ Name: "create",
+ Value: osCreate,
+ }, // create(name string) => imap(file)/error
+ "open": &tengo.UserFunction{
+ Name: "open",
+ Value: osOpen,
+ }, // open(name string) => imap(file)/error
+ "open_file": &tengo.UserFunction{
+ Name: "open_file",
+ Value: osOpenFile,
+ }, // open_file(name string, flag int, perm int) => imap(file)/error
+ "find_process": &tengo.UserFunction{
+ Name: "find_process",
+ Value: osFindProcess,
+ }, // find_process(pid int) => imap(process)/error
+ "start_process": &tengo.UserFunction{
+ Name: "start_process",
+ Value: osStartProcess,
+ }, // start_process(name string, argv array(string), dir string, env array(string)) => imap(process)/error
+ "exec_look_path": &tengo.UserFunction{
+ Name: "exec_look_path",
+ Value: FuncASRSE(exec.LookPath),
+ }, // exec_look_path(file) => string/error
+ "exec": &tengo.UserFunction{
+ Name: "exec",
+ Value: osExec,
+ }, // exec(name, args...) => command
+ "stat": &tengo.UserFunction{
+ Name: "stat",
+ Value: osStat,
+ }, // stat(name) => imap(fileinfo)/error
+ "read_file": &tengo.UserFunction{
+ Name: "read_file",
+ Value: osReadFile,
+ }, // readfile(name) => array(byte)/error
+}
+
+func osReadFile(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ fname, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ bytes, err := ioutil.ReadFile(fname)
+ if err != nil {
+ return wrapError(err), nil
+ }
+ if len(bytes) > tengo.MaxBytesLen {
+ return nil, tengo.ErrBytesLimit
+ }
+ return &tengo.Bytes{Value: bytes}, nil
+}
+
+func osStat(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ fname, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ stat, err := os.Stat(fname)
+ if err != nil {
+ return wrapError(err), nil
+ }
+ fstat := &tengo.ImmutableMap{
+ Value: map[string]tengo.Object{
+ "name": &tengo.String{Value: stat.Name()},
+ "mtime": &tengo.Time{Value: stat.ModTime()},
+ "size": &tengo.Int{Value: stat.Size()},
+ "mode": &tengo.Int{Value: int64(stat.Mode())},
+ },
+ }
+ if stat.IsDir() {
+ fstat.Value["directory"] = tengo.TrueValue
+ } else {
+ fstat.Value["directory"] = tengo.FalseValue
+ }
+ return fstat, nil
+}
+
+func osCreate(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ res, err := os.Create(s1)
+ if err != nil {
+ return wrapError(err), nil
+ }
+ return makeOSFile(res), nil
+}
+
+func osOpen(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ res, err := os.Open(s1)
+ if err != nil {
+ return wrapError(err), nil
+ }
+ return makeOSFile(res), nil
+}
+
+func osOpenFile(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 3 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ i3, ok := tengo.ToInt(args[2])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "int(compatible)",
+ Found: args[2].TypeName(),
+ }
+ }
+ res, err := os.OpenFile(s1, i2, os.FileMode(i3))
+ if err != nil {
+ return wrapError(err), nil
+ }
+ return makeOSFile(res), nil
+}
+
+func osArgs(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ arr := &tengo.Array{}
+ for _, osArg := range os.Args {
+ if len(osArg) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ arr.Value = append(arr.Value, &tengo.String{Value: osArg})
+ }
+ return arr, nil
+}
+
+func osFuncASFmRE(
+ name string,
+ fn func(string, os.FileMode) error,
+) *tengo.UserFunction {
+ return &tengo.UserFunction{
+ Name: name,
+ Value: func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ i2, ok := tengo.ToInt64(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ return wrapError(fn(s1, os.FileMode(i2))), nil
+ },
+ }
+}
+
+func osLookupEnv(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ res, ok := os.LookupEnv(s1)
+ if !ok {
+ return tengo.FalseValue, nil
+ }
+ if len(res) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ return &tengo.String{Value: res}, nil
+}
+
+func osExpandEnv(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ var vlen int
+ var failed bool
+ s := os.Expand(s1, func(k string) string {
+ if failed {
+ return ""
+ }
+ v := os.Getenv(k)
+
+ // this does not count the other texts that are not being replaced
+ // but the code checks the final length at the end
+ vlen += len(v)
+ if vlen > tengo.MaxStringLen {
+ failed = true
+ return ""
+ }
+ return v
+ })
+ if failed || len(s) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+ return &tengo.String{Value: s}, nil
+}
+
+func osExec(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) == 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ name, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ var execArgs []string
+ for idx, arg := range args[1:] {
+ execArg, ok := tengo.ToString(arg)
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: fmt.Sprintf("args[%d]", idx),
+ Expected: "string(compatible)",
+ Found: args[1+idx].TypeName(),
+ }
+ }
+ execArgs = append(execArgs, execArg)
+ }
+ return makeOSExecCommand(exec.Command(name, execArgs...)), nil
+}
+
+func osFindProcess(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ i1, ok := tengo.ToInt(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ proc, err := os.FindProcess(i1)
+ if err != nil {
+ return wrapError(err), nil
+ }
+ return makeOSProcess(proc), nil
+}
+
+func osStartProcess(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 4 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ name, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ var argv []string
+ var err error
+ switch arg1 := args[1].(type) {
+ case *tengo.Array:
+ argv, err = stringArray(arg1.Value, "second")
+ if err != nil {
+ return nil, err
+ }
+ case *tengo.ImmutableArray:
+ argv, err = stringArray(arg1.Value, "second")
+ if err != nil {
+ return nil, err
+ }
+ default:
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "array",
+ Found: arg1.TypeName(),
+ }
+ }
+
+ dir, ok := tengo.ToString(args[2])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "string(compatible)",
+ Found: args[2].TypeName(),
+ }
+ }
+
+ var env []string
+ switch arg3 := args[3].(type) {
+ case *tengo.Array:
+ env, err = stringArray(arg3.Value, "fourth")
+ if err != nil {
+ return nil, err
+ }
+ case *tengo.ImmutableArray:
+ env, err = stringArray(arg3.Value, "fourth")
+ if err != nil {
+ return nil, err
+ }
+ default:
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "fourth",
+ Expected: "array",
+ Found: arg3.TypeName(),
+ }
+ }
+
+ proc, err := os.StartProcess(name, argv, &os.ProcAttr{
+ Dir: dir,
+ Env: env,
+ })
+ if err != nil {
+ return wrapError(err), nil
+ }
+ return makeOSProcess(proc), nil
+}
+
+func stringArray(arr []tengo.Object, argName string) ([]string, error) {
+ var sarr []string
+ for idx, elem := range arr {
+ str, ok := elem.(*tengo.String)
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: fmt.Sprintf("%s[%d]", argName, idx),
+ Expected: "string",
+ Found: elem.TypeName(),
+ }
+ }
+ sarr = append(sarr, str.Value)
+ }
+ return sarr, nil
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/os_exec.go b/vendor/github.com/d5/tengo/v2/stdlib/os_exec.go
new file mode 100644
index 00000000..7ee5c1cd
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/os_exec.go
@@ -0,0 +1,119 @@
+package stdlib
+
+import (
+ "os/exec"
+
+ "github.com/d5/tengo/v2"
+)
+
+func makeOSExecCommand(cmd *exec.Cmd) *tengo.ImmutableMap {
+ return &tengo.ImmutableMap{
+ Value: map[string]tengo.Object{
+ // combined_output() => bytes/error
+ "combined_output": &tengo.UserFunction{
+ Name: "combined_output",
+ Value: FuncARYE(cmd.CombinedOutput),
+ },
+ // output() => bytes/error
+ "output": &tengo.UserFunction{
+ Name: "output",
+ Value: FuncARYE(cmd.Output),
+ }, //
+ // run() => error
+ "run": &tengo.UserFunction{
+ Name: "run",
+ Value: FuncARE(cmd.Run),
+ }, //
+ // start() => error
+ "start": &tengo.UserFunction{
+ Name: "start",
+ Value: FuncARE(cmd.Start),
+ }, //
+ // wait() => error
+ "wait": &tengo.UserFunction{
+ Name: "wait",
+ Value: FuncARE(cmd.Wait),
+ }, //
+ // set_path(path string)
+ "set_path": &tengo.UserFunction{
+ Name: "set_path",
+ Value: func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ cmd.Path = s1
+ return tengo.UndefinedValue, nil
+ },
+ },
+ // set_dir(dir string)
+ "set_dir": &tengo.UserFunction{
+ Name: "set_dir",
+ Value: func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ cmd.Dir = s1
+ return tengo.UndefinedValue, nil
+ },
+ },
+ // set_env(env array(string))
+ "set_env": &tengo.UserFunction{
+ Name: "set_env",
+ Value: func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+
+ var env []string
+ var err error
+ switch arg0 := args[0].(type) {
+ case *tengo.Array:
+ env, err = stringArray(arg0.Value, "first")
+ if err != nil {
+ return nil, err
+ }
+ case *tengo.ImmutableArray:
+ env, err = stringArray(arg0.Value, "first")
+ if err != nil {
+ return nil, err
+ }
+ default:
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "array",
+ Found: arg0.TypeName(),
+ }
+ }
+ cmd.Env = env
+ return tengo.UndefinedValue, nil
+ },
+ },
+ // process() => imap(process)
+ "process": &tengo.UserFunction{
+ Name: "process",
+ Value: func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ return makeOSProcess(cmd.Process), nil
+ },
+ },
+ },
+ }
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/os_file.go b/vendor/github.com/d5/tengo/v2/stdlib/os_file.go
new file mode 100644
index 00000000..4f59b4c4
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/os_file.go
@@ -0,0 +1,117 @@
+package stdlib
+
+import (
+ "os"
+
+ "github.com/d5/tengo/v2"
+)
+
+func makeOSFile(file *os.File) *tengo.ImmutableMap {
+ return &tengo.ImmutableMap{
+ Value: map[string]tengo.Object{
+ // chdir() => true/error
+ "chdir": &tengo.UserFunction{
+ Name: "chdir",
+ Value: FuncARE(file.Chdir),
+ }, //
+ // chown(uid int, gid int) => true/error
+ "chown": &tengo.UserFunction{
+ Name: "chown",
+ Value: FuncAIIRE(file.Chown),
+ }, //
+ // close() => error
+ "close": &tengo.UserFunction{
+ Name: "close",
+ Value: FuncARE(file.Close),
+ }, //
+ // name() => string
+ "name": &tengo.UserFunction{
+ Name: "name",
+ Value: FuncARS(file.Name),
+ }, //
+ // readdirnames(n int) => array(string)/error
+ "readdirnames": &tengo.UserFunction{
+ Name: "readdirnames",
+ Value: FuncAIRSsE(file.Readdirnames),
+ }, //
+ // sync() => error
+ "sync": &tengo.UserFunction{
+ Name: "sync",
+ Value: FuncARE(file.Sync),
+ }, //
+ // write(bytes) => int/error
+ "write": &tengo.UserFunction{
+ Name: "write",
+ Value: FuncAYRIE(file.Write),
+ }, //
+ // write(string) => int/error
+ "write_string": &tengo.UserFunction{
+ Name: "write_string",
+ Value: FuncASRIE(file.WriteString),
+ }, //
+ // read(bytes) => int/error
+ "read": &tengo.UserFunction{
+ Name: "read",
+ Value: FuncAYRIE(file.Read),
+ }, //
+ // chmod(mode int) => error
+ "chmod": &tengo.UserFunction{
+ Name: "chmod",
+ Value: func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ i1, ok := tengo.ToInt64(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ return wrapError(file.Chmod(os.FileMode(i1))), nil
+ },
+ },
+ // seek(offset int, whence int) => int/error
+ "seek": &tengo.UserFunction{
+ Name: "seek",
+ Value: func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ i1, ok := tengo.ToInt64(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+ res, err := file.Seek(i1, i2)
+ if err != nil {
+ return wrapError(err), nil
+ }
+ return &tengo.Int{Value: res}, nil
+ },
+ },
+ // stat() => imap(fileinfo)/error
+ "stat": &tengo.UserFunction{
+ Name: "stat",
+ Value: func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ return osStat(&tengo.String{Value: file.Name()})
+ },
+ },
+ },
+ }
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/os_process.go b/vendor/github.com/d5/tengo/v2/stdlib/os_process.go
new file mode 100644
index 00000000..7fcf27a4
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/os_process.go
@@ -0,0 +1,76 @@
+package stdlib
+
+import (
+ "os"
+ "syscall"
+
+ "github.com/d5/tengo/v2"
+)
+
+func makeOSProcessState(state *os.ProcessState) *tengo.ImmutableMap {
+ return &tengo.ImmutableMap{
+ Value: map[string]tengo.Object{
+ "exited": &tengo.UserFunction{
+ Name: "exited",
+ Value: FuncARB(state.Exited),
+ },
+ "pid": &tengo.UserFunction{
+ Name: "pid",
+ Value: FuncARI(state.Pid),
+ },
+ "string": &tengo.UserFunction{
+ Name: "string",
+ Value: FuncARS(state.String),
+ },
+ "success": &tengo.UserFunction{
+ Name: "success",
+ Value: FuncARB(state.Success),
+ },
+ },
+ }
+}
+
+func makeOSProcess(proc *os.Process) *tengo.ImmutableMap {
+ return &tengo.ImmutableMap{
+ Value: map[string]tengo.Object{
+ "kill": &tengo.UserFunction{
+ Name: "kill",
+ Value: FuncARE(proc.Kill),
+ },
+ "release": &tengo.UserFunction{
+ Name: "release",
+ Value: FuncARE(proc.Release),
+ },
+ "signal": &tengo.UserFunction{
+ Name: "signal",
+ Value: func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ i1, ok := tengo.ToInt64(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ return wrapError(proc.Signal(syscall.Signal(i1))), nil
+ },
+ },
+ "wait": &tengo.UserFunction{
+ Name: "wait",
+ Value: func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 0 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ state, err := proc.Wait()
+ if err != nil {
+ return wrapError(err), nil
+ }
+ return makeOSProcessState(state), nil
+ },
+ },
+ },
+ }
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/rand.go b/vendor/github.com/d5/tengo/v2/stdlib/rand.go
new file mode 100644
index 00000000..5d21e1df
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/rand.go
@@ -0,0 +1,138 @@
+package stdlib
+
+import (
+ "math/rand"
+
+ "github.com/d5/tengo/v2"
+)
+
+var randModule = map[string]tengo.Object{
+ "int": &tengo.UserFunction{
+ Name: "int",
+ Value: FuncARI64(rand.Int63),
+ },
+ "float": &tengo.UserFunction{
+ Name: "float",
+ Value: FuncARF(rand.Float64),
+ },
+ "intn": &tengo.UserFunction{
+ Name: "intn",
+ Value: FuncAI64RI64(rand.Int63n),
+ },
+ "exp_float": &tengo.UserFunction{
+ Name: "exp_float",
+ Value: FuncARF(rand.ExpFloat64),
+ },
+ "norm_float": &tengo.UserFunction{
+ Name: "norm_float",
+ Value: FuncARF(rand.NormFloat64),
+ },
+ "perm": &tengo.UserFunction{
+ Name: "perm",
+ Value: FuncAIRIs(rand.Perm),
+ },
+ "seed": &tengo.UserFunction{
+ Name: "seed",
+ Value: FuncAI64R(rand.Seed),
+ },
+ "read": &tengo.UserFunction{
+ Name: "read",
+ Value: func(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ y1, ok := args[0].(*tengo.Bytes)
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "bytes",
+ Found: args[0].TypeName(),
+ }
+ }
+ res, err := rand.Read(y1.Value)
+ if err != nil {
+ ret = wrapError(err)
+ return
+ }
+ return &tengo.Int{Value: int64(res)}, nil
+ },
+ },
+ "rand": &tengo.UserFunction{
+ Name: "rand",
+ Value: func(args ...tengo.Object) (tengo.Object, error) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ i1, ok := tengo.ToInt64(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+ src := rand.NewSource(i1)
+ return randRand(rand.New(src)), nil
+ },
+ },
+}
+
+func randRand(r *rand.Rand) *tengo.ImmutableMap {
+ return &tengo.ImmutableMap{
+ Value: map[string]tengo.Object{
+ "int": &tengo.UserFunction{
+ Name: "int",
+ Value: FuncARI64(r.Int63),
+ },
+ "float": &tengo.UserFunction{
+ Name: "float",
+ Value: FuncARF(r.Float64),
+ },
+ "intn": &tengo.UserFunction{
+ Name: "intn",
+ Value: FuncAI64RI64(r.Int63n),
+ },
+ "exp_float": &tengo.UserFunction{
+ Name: "exp_float",
+ Value: FuncARF(r.ExpFloat64),
+ },
+ "norm_float": &tengo.UserFunction{
+ Name: "norm_float",
+ Value: FuncARF(r.NormFloat64),
+ },
+ "perm": &tengo.UserFunction{
+ Name: "perm",
+ Value: FuncAIRIs(r.Perm),
+ },
+ "seed": &tengo.UserFunction{
+ Name: "seed",
+ Value: FuncAI64R(r.Seed),
+ },
+ "read": &tengo.UserFunction{
+ Name: "read",
+ Value: func(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+ ) {
+ if len(args) != 1 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+ y1, ok := args[0].(*tengo.Bytes)
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "bytes",
+ Found: args[0].TypeName(),
+ }
+ }
+ res, err := r.Read(y1.Value)
+ if err != nil {
+ ret = wrapError(err)
+ return
+ }
+ return &tengo.Int{Value: int64(res)}, nil
+ },
+ },
+ },
+ }
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/source_modules.go b/vendor/github.com/d5/tengo/v2/stdlib/source_modules.go
new file mode 100644
index 00000000..ca69d7d1
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/source_modules.go
@@ -0,0 +1,8 @@
+// Code generated using gensrcmods.go; DO NOT EDIT.
+
+package stdlib
+
+// SourceModules are source type standard library modules.
+var SourceModules = map[string]string{
+ "enum": "is_enumerable := func(x) {\n return is_array(x) || is_map(x) || is_immutable_array(x) || is_immutable_map(x)\n}\n\nis_array_like := func(x) {\n return is_array(x) || is_immutable_array(x)\n}\n\nexport {\n // all returns true if the given function `fn` evaluates to a truthy value on\n // all of the items in `x`. It returns undefined if `x` is not enumerable.\n all: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if !fn(k, v) { return false }\n }\n\n return true\n },\n // any returns true if the given function `fn` evaluates to a truthy value on\n // any of the items in `x`. It returns undefined if `x` is not enumerable.\n any: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return true }\n }\n\n return false\n },\n // chunk returns an array of elements split into groups the length of size.\n // If `x` can't be split evenly, the final chunk will be the remaining elements.\n // It returns undefined if `x` is not array.\n chunk: func(x, size) {\n if !is_array_like(x) || !size { return undefined }\n\n numElements := len(x)\n if !numElements { return [] }\n\n res := []\n idx := 0\n for idx < numElements {\n res = append(res, x[idx:idx+size])\n idx += size\n }\n\n return res\n },\n // at returns an element at the given index (if `x` is array) or\n // key (if `x` is map). It returns undefined if `x` is not enumerable.\n at: func(x, key) {\n if !is_enumerable(x) { return undefined }\n\n if is_array_like(x) {\n if !is_int(key) { return undefined }\n } else {\n if !is_string(key) { return undefined }\n }\n\n return x[key]\n },\n // each iterates over elements of `x` and invokes `fn` for each element. `fn` is\n // invoked with two arguments: `key` and `value`. `key` is an int index\n // if `x` is array. `key` is a string key if `x` is map. It does not iterate\n // and returns undefined if `x` is not enumerable.\n each: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n fn(k, v)\n }\n },\n // filter iterates over elements of `x`, returning an array of all elements `fn`\n // returns truthy for. `fn` is invoked with two arguments: `key` and `value`.\n // `key` is an int index if `x` is array. `key` is a string key if `x` is map.\n // It returns undefined if `x` is not enumerable.\n filter: func(x, fn) {\n if !is_array_like(x) { return undefined }\n\n dst := []\n for k, v in x {\n if fn(k, v) { dst = append(dst, v) }\n }\n\n return dst\n },\n // find iterates over elements of `x`, returning value of the first element `fn`\n // returns truthy for. `fn` is invoked with two arguments: `key` and `value`.\n // `key` is an int index if `x` is array. `key` is a string key if `x` is map.\n // It returns undefined if `x` is not enumerable.\n find: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return v }\n }\n },\n // find_key iterates over elements of `x`, returning key or index of the first\n // element `fn` returns truthy for. `fn` is invoked with two arguments: `key`\n // and `value`. `key` is an int index if `x` is array. `key` is a string key if\n // `x` is map. It returns undefined if `x` is not enumerable.\n find_key: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return k }\n }\n },\n // map creates an array of values by running each element in `x` through `fn`.\n // `fn` is invoked with two arguments: `key` and `value`. `key` is an int index\n // if `x` is array. `key` is a string key if `x` is map. It returns undefined\n // if `x` is not enumerable.\n map: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n dst := []\n for k, v in x {\n dst = append(dst, fn(k, v))\n }\n\n return dst\n },\n // key returns the first argument.\n key: func(k, _) { return k },\n // value returns the second argument.\n value: func(_, v) { return v }\n}\n",
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/srcmod_enum.tengo b/vendor/github.com/d5/tengo/v2/stdlib/srcmod_enum.tengo
new file mode 100644
index 00000000..7a5ea637
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/srcmod_enum.tengo
@@ -0,0 +1,128 @@
+is_enumerable := func(x) {
+ return is_array(x) || is_map(x) || is_immutable_array(x) || is_immutable_map(x)
+}
+
+is_array_like := func(x) {
+ return is_array(x) || is_immutable_array(x)
+}
+
+export {
+ // all returns true if the given function `fn` evaluates to a truthy value on
+ // all of the items in `x`. It returns undefined if `x` is not enumerable.
+ all: func(x, fn) {
+ if !is_enumerable(x) { return undefined }
+
+ for k, v in x {
+ if !fn(k, v) { return false }
+ }
+
+ return true
+ },
+ // any returns true if the given function `fn` evaluates to a truthy value on
+ // any of the items in `x`. It returns undefined if `x` is not enumerable.
+ any: func(x, fn) {
+ if !is_enumerable(x) { return undefined }
+
+ for k, v in x {
+ if fn(k, v) { return true }
+ }
+
+ return false
+ },
+ // chunk returns an array of elements split into groups the length of size.
+ // If `x` can't be split evenly, the final chunk will be the remaining elements.
+ // It returns undefined if `x` is not array.
+ chunk: func(x, size) {
+ if !is_array_like(x) || !size { return undefined }
+
+ numElements := len(x)
+ if !numElements { return [] }
+
+ res := []
+ idx := 0
+ for idx < numElements {
+ res = append(res, x[idx:idx+size])
+ idx += size
+ }
+
+ return res
+ },
+ // at returns an element at the given index (if `x` is array) or
+ // key (if `x` is map). It returns undefined if `x` is not enumerable.
+ at: func(x, key) {
+ if !is_enumerable(x) { return undefined }
+
+ if is_array_like(x) {
+ if !is_int(key) { return undefined }
+ } else {
+ if !is_string(key) { return undefined }
+ }
+
+ return x[key]
+ },
+ // each iterates over elements of `x` and invokes `fn` for each element. `fn` is
+ // invoked with two arguments: `key` and `value`. `key` is an int index
+ // if `x` is array. `key` is a string key if `x` is map. It does not iterate
+ // and returns undefined if `x` is not enumerable.
+ each: func(x, fn) {
+ if !is_enumerable(x) { return undefined }
+
+ for k, v in x {
+ fn(k, v)
+ }
+ },
+ // filter iterates over elements of `x`, returning an array of all elements `fn`
+ // returns truthy for. `fn` is invoked with two arguments: `key` and `value`.
+ // `key` is an int index if `x` is array. `key` is a string key if `x` is map.
+ // It returns undefined if `x` is not enumerable.
+ filter: func(x, fn) {
+ if !is_array_like(x) { return undefined }
+
+ dst := []
+ for k, v in x {
+ if fn(k, v) { dst = append(dst, v) }
+ }
+
+ return dst
+ },
+ // find iterates over elements of `x`, returning value of the first element `fn`
+ // returns truthy for. `fn` is invoked with two arguments: `key` and `value`.
+ // `key` is an int index if `x` is array. `key` is a string key if `x` is map.
+ // It returns undefined if `x` is not enumerable.
+ find: func(x, fn) {
+ if !is_enumerable(x) { return undefined }
+
+ for k, v in x {
+ if fn(k, v) { return v }
+ }
+ },
+ // find_key iterates over elements of `x`, returning key or index of the first
+ // element `fn` returns truthy for. `fn` is invoked with two arguments: `key`
+ // and `value`. `key` is an int index if `x` is array. `key` is a string key if
+ // `x` is map. It returns undefined if `x` is not enumerable.
+ find_key: func(x, fn) {
+ if !is_enumerable(x) { return undefined }
+
+ for k, v in x {
+ if fn(k, v) { return k }
+ }
+ },
+ // map creates an array of values by running each element in `x` through `fn`.
+ // `fn` is invoked with two arguments: `key` and `value`. `key` is an int index
+ // if `x` is array. `key` is a string key if `x` is map. It returns undefined
+ // if `x` is not enumerable.
+ map: func(x, fn) {
+ if !is_enumerable(x) { return undefined }
+
+ dst := []
+ for k, v in x {
+ dst = append(dst, fn(k, v))
+ }
+
+ return dst
+ },
+ // key returns the first argument.
+ key: func(k, _) { return k },
+ // value returns the second argument.
+ value: func(_, v) { return v }
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/stdlib.go b/vendor/github.com/d5/tengo/v2/stdlib/stdlib.go
new file mode 100644
index 00000000..16c369a0
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/stdlib.go
@@ -0,0 +1,34 @@
+package stdlib
+
+//go:generate go run gensrcmods.go
+
+import (
+ "github.com/d5/tengo/v2"
+)
+
+// AllModuleNames returns a list of all default module names.
+func AllModuleNames() []string {
+ var names []string
+ for name := range BuiltinModules {
+ names = append(names, name)
+ }
+ for name := range SourceModules {
+ names = append(names, name)
+ }
+ return names
+}
+
+// GetModuleMap returns the module map that includes all modules
+// for the given module names.
+func GetModuleMap(names ...string) *tengo.ModuleMap {
+ modules := tengo.NewModuleMap()
+ for _, name := range names {
+ if mod := BuiltinModules[name]; mod != nil {
+ modules.AddBuiltinModule(name, mod)
+ }
+ if mod := SourceModules[name]; mod != "" {
+ modules.AddSourceModule(name, []byte(mod))
+ }
+ }
+ return modules
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/text.go b/vendor/github.com/d5/tengo/v2/stdlib/text.go
new file mode 100644
index 00000000..d7d5d1da
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/text.go
@@ -0,0 +1,1072 @@
+package stdlib
+
+import (
+ "fmt"
+ "regexp"
+ "strconv"
+ "strings"
+ "unicode/utf8"
+
+ "github.com/d5/tengo/v2"
+)
+
+var textModule = map[string]tengo.Object{
+ "re_match": &tengo.UserFunction{
+ Name: "re_match",
+ Value: textREMatch,
+ }, // re_match(pattern, text) => bool/error
+ "re_find": &tengo.UserFunction{
+ Name: "re_find",
+ Value: textREFind,
+ }, // re_find(pattern, text, count) => [[{text:,begin:,end:}]]/undefined
+ "re_replace": &tengo.UserFunction{
+ Name: "re_replace",
+ Value: textREReplace,
+ }, // re_replace(pattern, text, repl) => string/error
+ "re_split": &tengo.UserFunction{
+ Name: "re_split",
+ Value: textRESplit,
+ }, // re_split(pattern, text, count) => [string]/error
+ "re_compile": &tengo.UserFunction{
+ Name: "re_compile",
+ Value: textRECompile,
+ }, // re_compile(pattern) => Regexp/error
+ "compare": &tengo.UserFunction{
+ Name: "compare",
+ Value: FuncASSRI(strings.Compare),
+ }, // compare(a, b) => int
+ "contains": &tengo.UserFunction{
+ Name: "contains",
+ Value: FuncASSRB(strings.Contains),
+ }, // contains(s, substr) => bool
+ "contains_any": &tengo.UserFunction{
+ Name: "contains_any",
+ Value: FuncASSRB(strings.ContainsAny),
+ }, // contains_any(s, chars) => bool
+ "count": &tengo.UserFunction{
+ Name: "count",
+ Value: FuncASSRI(strings.Count),
+ }, // count(s, substr) => int
+ "equal_fold": &tengo.UserFunction{
+ Name: "equal_fold",
+ Value: FuncASSRB(strings.EqualFold),
+ }, // "equal_fold(s, t) => bool
+ "fields": &tengo.UserFunction{
+ Name: "fields",
+ Value: FuncASRSs(strings.Fields),
+ }, // fields(s) => [string]
+ "has_prefix": &tengo.UserFunction{
+ Name: "has_prefix",
+ Value: FuncASSRB(strings.HasPrefix),
+ }, // has_prefix(s, prefix) => bool
+ "has_suffix": &tengo.UserFunction{
+ Name: "has_suffix",
+ Value: FuncASSRB(strings.HasSuffix),
+ }, // has_suffix(s, suffix) => bool
+ "index": &tengo.UserFunction{
+ Name: "index",
+ Value: FuncASSRI(strings.Index),
+ }, // index(s, substr) => int
+ "index_any": &tengo.UserFunction{
+ Name: "index_any",
+ Value: FuncASSRI(strings.IndexAny),
+ }, // index_any(s, chars) => int
+ "join": &tengo.UserFunction{
+ Name: "join",
+ Value: textJoin,
+ }, // join(arr, sep) => string
+ "last_index": &tengo.UserFunction{
+ Name: "last_index",
+ Value: FuncASSRI(strings.LastIndex),
+ }, // last_index(s, substr) => int
+ "last_index_any": &tengo.UserFunction{
+ Name: "last_index_any",
+ Value: FuncASSRI(strings.LastIndexAny),
+ }, // last_index_any(s, chars) => int
+ "repeat": &tengo.UserFunction{
+ Name: "repeat",
+ Value: textRepeat,
+ }, // repeat(s, count) => string
+ "replace": &tengo.UserFunction{
+ Name: "replace",
+ Value: textReplace,
+ }, // replace(s, old, new, n) => string
+ "substr": &tengo.UserFunction{
+ Name: "substr",
+ Value: textSubstring,
+ }, // substr(s, lower, upper) => string
+ "split": &tengo.UserFunction{
+ Name: "split",
+ Value: FuncASSRSs(strings.Split),
+ }, // split(s, sep) => [string]
+ "split_after": &tengo.UserFunction{
+ Name: "split_after",
+ Value: FuncASSRSs(strings.SplitAfter),
+ }, // split_after(s, sep) => [string]
+ "split_after_n": &tengo.UserFunction{
+ Name: "split_after_n",
+ Value: FuncASSIRSs(strings.SplitAfterN),
+ }, // split_after_n(s, sep, n) => [string]
+ "split_n": &tengo.UserFunction{
+ Name: "split_n",
+ Value: FuncASSIRSs(strings.SplitN),
+ }, // split_n(s, sep, n) => [string]
+ "title": &tengo.UserFunction{
+ Name: "title",
+ Value: FuncASRS(strings.Title),
+ }, // title(s) => string
+ "to_lower": &tengo.UserFunction{
+ Name: "to_lower",
+ Value: FuncASRS(strings.ToLower),
+ }, // to_lower(s) => string
+ "to_title": &tengo.UserFunction{
+ Name: "to_title",
+ Value: FuncASRS(strings.ToTitle),
+ }, // to_title(s) => string
+ "to_upper": &tengo.UserFunction{
+ Name: "to_upper",
+ Value: FuncASRS(strings.ToUpper),
+ }, // to_upper(s) => string
+ "pad_left": &tengo.UserFunction{
+ Name: "pad_left",
+ Value: textPadLeft,
+ }, // pad_left(s, pad_len, pad_with) => string
+ "pad_right": &tengo.UserFunction{
+ Name: "pad_right",
+ Value: textPadRight,
+ }, // pad_right(s, pad_len, pad_with) => string
+ "trim": &tengo.UserFunction{
+ Name: "trim",
+ Value: FuncASSRS(strings.Trim),
+ }, // trim(s, cutset) => string
+ "trim_left": &tengo.UserFunction{
+ Name: "trim_left",
+ Value: FuncASSRS(strings.TrimLeft),
+ }, // trim_left(s, cutset) => string
+ "trim_prefix": &tengo.UserFunction{
+ Name: "trim_prefix",
+ Value: FuncASSRS(strings.TrimPrefix),
+ }, // trim_prefix(s, prefix) => string
+ "trim_right": &tengo.UserFunction{
+ Name: "trim_right",
+ Value: FuncASSRS(strings.TrimRight),
+ }, // trim_right(s, cutset) => string
+ "trim_space": &tengo.UserFunction{
+ Name: "trim_space",
+ Value: FuncASRS(strings.TrimSpace),
+ }, // trim_space(s) => string
+ "trim_suffix": &tengo.UserFunction{
+ Name: "trim_suffix",
+ Value: FuncASSRS(strings.TrimSuffix),
+ }, // trim_suffix(s, suffix) => string
+ "atoi": &tengo.UserFunction{
+ Name: "atoi",
+ Value: FuncASRIE(strconv.Atoi),
+ }, // atoi(str) => int/error
+ "format_bool": &tengo.UserFunction{
+ Name: "format_bool",
+ Value: textFormatBool,
+ }, // format_bool(b) => string
+ "format_float": &tengo.UserFunction{
+ Name: "format_float",
+ Value: textFormatFloat,
+ }, // format_float(f, fmt, prec, bits) => string
+ "format_int": &tengo.UserFunction{
+ Name: "format_int",
+ Value: textFormatInt,
+ }, // format_int(i, base) => string
+ "itoa": &tengo.UserFunction{
+ Name: "itoa",
+ Value: FuncAIRS(strconv.Itoa),
+ }, // itoa(i) => string
+ "parse_bool": &tengo.UserFunction{
+ Name: "parse_bool",
+ Value: textParseBool,
+ }, // parse_bool(str) => bool/error
+ "parse_float": &tengo.UserFunction{
+ Name: "parse_float",
+ Value: textParseFloat,
+ }, // parse_float(str, bits) => float/error
+ "parse_int": &tengo.UserFunction{
+ Name: "parse_int",
+ Value: textParseInt,
+ }, // parse_int(str, base, bits) => int/error
+ "quote": &tengo.UserFunction{
+ Name: "quote",
+ Value: FuncASRS(strconv.Quote),
+ }, // quote(str) => string
+ "unquote": &tengo.UserFunction{
+ Name: "unquote",
+ Value: FuncASRSE(strconv.Unquote),
+ }, // unquote(str) => string/error
+}
+
+func textREMatch(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ matched, err := regexp.MatchString(s1, s2)
+ if err != nil {
+ ret = wrapError(err)
+ return
+ }
+
+ if matched {
+ ret = tengo.TrueValue
+ } else {
+ ret = tengo.FalseValue
+ }
+
+ return
+}
+
+func textREFind(args ...tengo.Object) (ret tengo.Object, err error) {
+ numArgs := len(args)
+ if numArgs != 2 && numArgs != 3 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ re, err := regexp.Compile(s1)
+ if err != nil {
+ ret = wrapError(err)
+ return
+ }
+
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ if numArgs < 3 {
+ m := re.FindStringSubmatchIndex(s2)
+ if m == nil {
+ ret = tengo.UndefinedValue
+ return
+ }
+
+ arr := &tengo.Array{}
+ for i := 0; i < len(m); i += 2 {
+ arr.Value = append(arr.Value,
+ &tengo.ImmutableMap{Value: map[string]tengo.Object{
+ "text": &tengo.String{Value: s2[m[i]:m[i+1]]},
+ "begin": &tengo.Int{Value: int64(m[i])},
+ "end": &tengo.Int{Value: int64(m[i+1])},
+ }})
+ }
+
+ ret = &tengo.Array{Value: []tengo.Object{arr}}
+
+ return
+ }
+
+ i3, ok := tengo.ToInt(args[2])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "int(compatible)",
+ Found: args[2].TypeName(),
+ }
+ return
+ }
+ m := re.FindAllStringSubmatchIndex(s2, i3)
+ if m == nil {
+ ret = tengo.UndefinedValue
+ return
+ }
+
+ arr := &tengo.Array{}
+ for _, m := range m {
+ subMatch := &tengo.Array{}
+ for i := 0; i < len(m); i += 2 {
+ subMatch.Value = append(subMatch.Value,
+ &tengo.ImmutableMap{Value: map[string]tengo.Object{
+ "text": &tengo.String{Value: s2[m[i]:m[i+1]]},
+ "begin": &tengo.Int{Value: int64(m[i])},
+ "end": &tengo.Int{Value: int64(m[i+1])},
+ }})
+ }
+
+ arr.Value = append(arr.Value, subMatch)
+ }
+
+ ret = arr
+
+ return
+}
+
+func textREReplace(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 3 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ s3, ok := tengo.ToString(args[2])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "string(compatible)",
+ Found: args[2].TypeName(),
+ }
+ return
+ }
+
+ re, err := regexp.Compile(s1)
+ if err != nil {
+ ret = wrapError(err)
+ } else {
+ s, ok := doTextRegexpReplace(re, s2, s3)
+ if !ok {
+ return nil, tengo.ErrStringLimit
+ }
+
+ ret = &tengo.String{Value: s}
+ }
+
+ return
+}
+
+func textRESplit(args ...tengo.Object) (ret tengo.Object, err error) {
+ numArgs := len(args)
+ if numArgs != 2 && numArgs != 3 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ var i3 = -1
+ if numArgs > 2 {
+ i3, ok = tengo.ToInt(args[2])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "int(compatible)",
+ Found: args[2].TypeName(),
+ }
+ return
+ }
+ }
+
+ re, err := regexp.Compile(s1)
+ if err != nil {
+ ret = wrapError(err)
+ return
+ }
+
+ arr := &tengo.Array{}
+ for _, s := range re.Split(s2, i3) {
+ arr.Value = append(arr.Value, &tengo.String{Value: s})
+ }
+
+ ret = arr
+
+ return
+}
+
+func textRECompile(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ re, err := regexp.Compile(s1)
+ if err != nil {
+ ret = wrapError(err)
+ } else {
+ ret = makeTextRegexp(re)
+ }
+
+ return
+}
+
+func textReplace(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 4 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ s3, ok := tengo.ToString(args[2])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "string(compatible)",
+ Found: args[2].TypeName(),
+ }
+ return
+ }
+
+ i4, ok := tengo.ToInt(args[3])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "fourth",
+ Expected: "int(compatible)",
+ Found: args[3].TypeName(),
+ }
+ return
+ }
+
+ s, ok := doTextReplace(s1, s2, s3, i4)
+ if !ok {
+ err = tengo.ErrStringLimit
+ return
+ }
+
+ ret = &tengo.String{Value: s}
+
+ return
+}
+
+func textSubstring(args ...tengo.Object) (ret tengo.Object, err error) {
+ argslen := len(args)
+ if argslen != 2 && argslen != 3 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ strlen := len(s1)
+ i3 := strlen
+ if argslen == 3 {
+ i3, ok = tengo.ToInt(args[2])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "int(compatible)",
+ Found: args[2].TypeName(),
+ }
+ return
+ }
+ }
+
+ if i2 > i3 {
+ err = tengo.ErrInvalidIndexType
+ return
+ }
+
+ if i2 < 0 {
+ i2 = 0
+ } else if i2 > strlen {
+ i2 = strlen
+ }
+
+ if i3 < 0 {
+ i3 = 0
+ } else if i3 > strlen {
+ i3 = strlen
+ }
+
+ ret = &tengo.String{Value: s1[i2:i3]}
+
+ return
+}
+
+func textPadLeft(args ...tengo.Object) (ret tengo.Object, err error) {
+ argslen := len(args)
+ if argslen != 2 && argslen != 3 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ if i2 > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+
+ sLen := len(s1)
+ if sLen >= i2 {
+ ret = &tengo.String{Value: s1}
+ return
+ }
+
+ s3 := " "
+ if argslen == 3 {
+ s3, ok = tengo.ToString(args[2])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "string(compatible)",
+ Found: args[2].TypeName(),
+ }
+ return
+ }
+ }
+
+ padStrLen := len(s3)
+ if padStrLen == 0 {
+ ret = &tengo.String{Value: s1}
+ return
+ }
+
+ padCount := ((i2 - padStrLen) / padStrLen) + 1
+ retStr := strings.Repeat(s3, padCount) + s1
+ ret = &tengo.String{Value: retStr[len(retStr)-i2:]}
+
+ return
+}
+
+func textPadRight(args ...tengo.Object) (ret tengo.Object, err error) {
+ argslen := len(args)
+ if argslen != 2 && argslen != 3 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ if i2 > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+
+ sLen := len(s1)
+ if sLen >= i2 {
+ ret = &tengo.String{Value: s1}
+ return
+ }
+
+ s3 := " "
+ if argslen == 3 {
+ s3, ok = tengo.ToString(args[2])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "string(compatible)",
+ Found: args[2].TypeName(),
+ }
+ return
+ }
+ }
+
+ padStrLen := len(s3)
+ if padStrLen == 0 {
+ ret = &tengo.String{Value: s1}
+ return
+ }
+
+ padCount := ((i2 - padStrLen) / padStrLen) + 1
+ retStr := s1 + strings.Repeat(s3, padCount)
+ ret = &tengo.String{Value: retStr[:i2]}
+
+ return
+}
+
+func textRepeat(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ }
+
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+
+ if len(s1)*i2 > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+
+ return &tengo.String{Value: strings.Repeat(s1, i2)}, nil
+}
+
+func textJoin(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ return nil, tengo.ErrWrongNumArguments
+ }
+
+ var slen int
+ var ss1 []string
+ switch arg0 := args[0].(type) {
+ case *tengo.Array:
+ for idx, a := range arg0.Value {
+ as, ok := tengo.ToString(a)
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: fmt.Sprintf("first[%d]", idx),
+ Expected: "string(compatible)",
+ Found: a.TypeName(),
+ }
+ }
+ slen += len(as)
+ ss1 = append(ss1, as)
+ }
+ case *tengo.ImmutableArray:
+ for idx, a := range arg0.Value {
+ as, ok := tengo.ToString(a)
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: fmt.Sprintf("first[%d]", idx),
+ Expected: "string(compatible)",
+ Found: a.TypeName(),
+ }
+ }
+ slen += len(as)
+ ss1 = append(ss1, as)
+ }
+ default:
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "array",
+ Found: args[0].TypeName(),
+ }
+ }
+
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ return nil, tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ }
+
+ // make sure output length does not exceed the limit
+ if slen+len(s2)*(len(ss1)-1) > tengo.MaxStringLen {
+ return nil, tengo.ErrStringLimit
+ }
+
+ return &tengo.String{Value: strings.Join(ss1, s2)}, nil
+}
+
+func textFormatBool(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ b1, ok := args[0].(*tengo.Bool)
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "bool",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ if b1 == tengo.TrueValue {
+ ret = &tengo.String{Value: "true"}
+ } else {
+ ret = &tengo.String{Value: "false"}
+ }
+
+ return
+}
+
+func textFormatFloat(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 4 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ f1, ok := args[0].(*tengo.Float)
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "float",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ i3, ok := tengo.ToInt(args[2])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "int(compatible)",
+ Found: args[2].TypeName(),
+ }
+ return
+ }
+
+ i4, ok := tengo.ToInt(args[3])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "fourth",
+ Expected: "int(compatible)",
+ Found: args[3].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.String{Value: strconv.FormatFloat(f1.Value, s2[0], i3, i4)}
+
+ return
+}
+
+func textFormatInt(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ i1, ok := args[0].(*tengo.Int)
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.String{Value: strconv.FormatInt(i1.Value, i2)}
+
+ return
+}
+
+func textParseBool(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := args[0].(*tengo.String)
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ parsed, err := strconv.ParseBool(s1.Value)
+ if err != nil {
+ ret = wrapError(err)
+ return
+ }
+
+ if parsed {
+ ret = tengo.TrueValue
+ } else {
+ ret = tengo.FalseValue
+ }
+
+ return
+}
+
+func textParseFloat(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := args[0].(*tengo.String)
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ parsed, err := strconv.ParseFloat(s1.Value, i2)
+ if err != nil {
+ ret = wrapError(err)
+ return
+ }
+
+ ret = &tengo.Float{Value: parsed}
+
+ return
+}
+
+func textParseInt(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 3 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := args[0].(*tengo.String)
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ i3, ok := tengo.ToInt(args[2])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "int(compatible)",
+ Found: args[2].TypeName(),
+ }
+ return
+ }
+
+ parsed, err := strconv.ParseInt(s1.Value, i2, i3)
+ if err != nil {
+ ret = wrapError(err)
+ return
+ }
+
+ ret = &tengo.Int{Value: parsed}
+
+ return
+}
+
+// Modified implementation of strings.Replace
+// to limit the maximum length of output string.
+func doTextReplace(s, old, new string, n int) (string, bool) {
+ if old == new || n == 0 {
+ return s, true // avoid allocation
+ }
+
+ // Compute number of replacements.
+ if m := strings.Count(s, old); m == 0 {
+ return s, true // avoid allocation
+ } else if n < 0 || m < n {
+ n = m
+ }
+
+ // Apply replacements to buffer.
+ t := make([]byte, len(s)+n*(len(new)-len(old)))
+ w := 0
+ start := 0
+ for i := 0; i < n; i++ {
+ j := start
+ if len(old) == 0 {
+ if i > 0 {
+ _, wid := utf8.DecodeRuneInString(s[start:])
+ j += wid
+ }
+ } else {
+ j += strings.Index(s[start:], old)
+ }
+
+ ssj := s[start:j]
+ if w+len(ssj)+len(new) > tengo.MaxStringLen {
+ return "", false
+ }
+
+ w += copy(t[w:], ssj)
+ w += copy(t[w:], new)
+ start = j + len(old)
+ }
+
+ ss := s[start:]
+ if w+len(ss) > tengo.MaxStringLen {
+ return "", false
+ }
+
+ w += copy(t[w:], ss)
+
+ return string(t[0:w]), true
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/text_regexp.go b/vendor/github.com/d5/tengo/v2/stdlib/text_regexp.go
new file mode 100644
index 00000000..1a7ecf07
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/text_regexp.go
@@ -0,0 +1,251 @@
+package stdlib
+
+import (
+ "regexp"
+
+ "github.com/d5/tengo/v2"
+)
+
+func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap {
+ return &tengo.ImmutableMap{
+ Value: map[string]tengo.Object{
+ // match(text) => bool
+ "match": &tengo.UserFunction{
+ Value: func(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+ ) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ if re.MatchString(s1) {
+ ret = tengo.TrueValue
+ } else {
+ ret = tengo.FalseValue
+ }
+
+ return
+ },
+ },
+
+ // find(text) => array(array({text:,begin:,end:}))/undefined
+ // find(text, maxCount) => array(array({text:,begin:,end:}))/undefined
+ "find": &tengo.UserFunction{
+ Value: func(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+ ) {
+ numArgs := len(args)
+ if numArgs != 1 && numArgs != 2 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ if numArgs == 1 {
+ m := re.FindStringSubmatchIndex(s1)
+ if m == nil {
+ ret = tengo.UndefinedValue
+ return
+ }
+
+ arr := &tengo.Array{}
+ for i := 0; i < len(m); i += 2 {
+ arr.Value = append(arr.Value,
+ &tengo.ImmutableMap{
+ Value: map[string]tengo.Object{
+ "text": &tengo.String{
+ Value: s1[m[i]:m[i+1]],
+ },
+ "begin": &tengo.Int{
+ Value: int64(m[i]),
+ },
+ "end": &tengo.Int{
+ Value: int64(m[i+1]),
+ },
+ }})
+ }
+
+ ret = &tengo.Array{Value: []tengo.Object{arr}}
+
+ return
+ }
+
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+ m := re.FindAllStringSubmatchIndex(s1, i2)
+ if m == nil {
+ ret = tengo.UndefinedValue
+ return
+ }
+
+ arr := &tengo.Array{}
+ for _, m := range m {
+ subMatch := &tengo.Array{}
+ for i := 0; i < len(m); i += 2 {
+ subMatch.Value = append(subMatch.Value,
+ &tengo.ImmutableMap{
+ Value: map[string]tengo.Object{
+ "text": &tengo.String{
+ Value: s1[m[i]:m[i+1]],
+ },
+ "begin": &tengo.Int{
+ Value: int64(m[i]),
+ },
+ "end": &tengo.Int{
+ Value: int64(m[i+1]),
+ },
+ }})
+ }
+
+ arr.Value = append(arr.Value, subMatch)
+ }
+
+ ret = arr
+
+ return
+ },
+ },
+
+ // replace(src, repl) => string
+ "replace": &tengo.UserFunction{
+ Value: func(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+ ) {
+ if len(args) != 2 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ s, ok := doTextRegexpReplace(re, s1, s2)
+ if !ok {
+ return nil, tengo.ErrStringLimit
+ }
+
+ ret = &tengo.String{Value: s}
+
+ return
+ },
+ },
+
+ // split(text) => array(string)
+ // split(text, maxCount) => array(string)
+ "split": &tengo.UserFunction{
+ Value: func(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+ ) {
+ numArgs := len(args)
+ if numArgs != 1 && numArgs != 2 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ var i2 = -1
+ if numArgs > 1 {
+ i2, ok = tengo.ToInt(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+ }
+
+ arr := &tengo.Array{}
+ for _, s := range re.Split(s1, i2) {
+ arr.Value = append(arr.Value,
+ &tengo.String{Value: s})
+ }
+
+ ret = arr
+
+ return
+ },
+ },
+ },
+ }
+}
+
+// Size-limit checking implementation of regexp.ReplaceAllString.
+func doTextRegexpReplace(re *regexp.Regexp, src, repl string) (string, bool) {
+ idx := 0
+ out := ""
+ for _, m := range re.FindAllStringSubmatchIndex(src, -1) {
+ var exp []byte
+ exp = re.ExpandString(exp, repl, src, m)
+ if len(out)+m[0]-idx+len(exp) > tengo.MaxStringLen {
+ return "", false
+ }
+ out += src[idx:m[0]] + string(exp)
+ idx = m[1]
+ }
+ if idx < len(src) {
+ if len(out)+len(src)-idx > tengo.MaxStringLen {
+ return "", false
+ }
+ out += src[idx:]
+ }
+ return out, true
+}
diff --git a/vendor/github.com/d5/tengo/v2/stdlib/times.go b/vendor/github.com/d5/tengo/v2/stdlib/times.go
new file mode 100644
index 00000000..0b6f7bd4
--- /dev/null
+++ b/vendor/github.com/d5/tengo/v2/stdlib/times.go
@@ -0,0 +1,1135 @@
+package stdlib
+
+import (
+ "time"
+
+ "github.com/d5/tengo/v2"
+)
+
+var timesModule = map[string]tengo.Object{
+ "format_ansic": &tengo.String{Value: time.ANSIC},
+ "format_unix_date": &tengo.String{Value: time.UnixDate},
+ "format_ruby_date": &tengo.String{Value: time.RubyDate},
+ "format_rfc822": &tengo.String{Value: time.RFC822},
+ "format_rfc822z": &tengo.String{Value: time.RFC822Z},
+ "format_rfc850": &tengo.String{Value: time.RFC850},
+ "format_rfc1123": &tengo.String{Value: time.RFC1123},
+ "format_rfc1123z": &tengo.String{Value: time.RFC1123Z},
+ "format_rfc3339": &tengo.String{Value: time.RFC3339},
+ "format_rfc3339_nano": &tengo.String{Value: time.RFC3339Nano},
+ "format_kitchen": &tengo.String{Value: time.Kitchen},
+ "format_stamp": &tengo.String{Value: time.Stamp},
+ "format_stamp_milli": &tengo.String{Value: time.StampMilli},
+ "format_stamp_micro": &tengo.String{Value: time.StampMicro},
+ "format_stamp_nano": &tengo.String{Value: time.StampNano},
+ "nanosecond": &tengo.Int{Value: int64(time.Nanosecond)},
+ "microsecond": &tengo.Int{Value: int64(time.Microsecond)},
+ "millisecond": &tengo.Int{Value: int64(time.Millisecond)},
+ "second": &tengo.Int{Value: int64(time.Second)},
+ "minute": &tengo.Int{Value: int64(time.Minute)},
+ "hour": &tengo.Int{Value: int64(time.Hour)},
+ "january": &tengo.Int{Value: int64(time.January)},
+ "february": &tengo.Int{Value: int64(time.February)},
+ "march": &tengo.Int{Value: int64(time.March)},
+ "april": &tengo.Int{Value: int64(time.April)},
+ "may": &tengo.Int{Value: int64(time.May)},
+ "june": &tengo.Int{Value: int64(time.June)},
+ "july": &tengo.Int{Value: int64(time.July)},
+ "august": &tengo.Int{Value: int64(time.August)},
+ "september": &tengo.Int{Value: int64(time.September)},
+ "october": &tengo.Int{Value: int64(time.October)},
+ "november": &tengo.Int{Value: int64(time.November)},
+ "december": &tengo.Int{Value: int64(time.December)},
+ "sleep": &tengo.UserFunction{
+ Name: "sleep",
+ Value: timesSleep,
+ }, // sleep(int)
+ "parse_duration": &tengo.UserFunction{
+ Name: "parse_duration",
+ Value: timesParseDuration,
+ }, // parse_duration(str) => int
+ "since": &tengo.UserFunction{
+ Name: "since",
+ Value: timesSince,
+ }, // since(time) => int
+ "until": &tengo.UserFunction{
+ Name: "until",
+ Value: timesUntil,
+ }, // until(time) => int
+ "duration_hours": &tengo.UserFunction{
+ Name: "duration_hours",
+ Value: timesDurationHours,
+ }, // duration_hours(int) => float
+ "duration_minutes": &tengo.UserFunction{
+ Name: "duration_minutes",
+ Value: timesDurationMinutes,
+ }, // duration_minutes(int) => float
+ "duration_nanoseconds": &tengo.UserFunction{
+ Name: "duration_nanoseconds",
+ Value: timesDurationNanoseconds,
+ }, // duration_nanoseconds(int) => int
+ "duration_seconds": &tengo.UserFunction{
+ Name: "duration_seconds",
+ Value: timesDurationSeconds,
+ }, // duration_seconds(int) => float
+ "duration_string": &tengo.UserFunction{
+ Name: "duration_string",
+ Value: timesDurationString,
+ }, // duration_string(int) => string
+ "month_string": &tengo.UserFunction{
+ Name: "month_string",
+ Value: timesMonthString,
+ }, // month_string(int) => string
+ "date": &tengo.UserFunction{
+ Name: "date",
+ Value: timesDate,
+ }, // date(year, month, day, hour, min, sec, nsec) => time
+ "now": &tengo.UserFunction{
+ Name: "now",
+ Value: timesNow,
+ }, // now() => time
+ "parse": &tengo.UserFunction{
+ Name: "parse",
+ Value: timesParse,
+ }, // parse(format, str) => time
+ "unix": &tengo.UserFunction{
+ Name: "unix",
+ Value: timesUnix,
+ }, // unix(sec, nsec) => time
+ "add": &tengo.UserFunction{
+ Name: "add",
+ Value: timesAdd,
+ }, // add(time, int) => time
+ "add_date": &tengo.UserFunction{
+ Name: "add_date",
+ Value: timesAddDate,
+ }, // add_date(time, years, months, days) => time
+ "sub": &tengo.UserFunction{
+ Name: "sub",
+ Value: timesSub,
+ }, // sub(t time, u time) => int
+ "after": &tengo.UserFunction{
+ Name: "after",
+ Value: timesAfter,
+ }, // after(t time, u time) => bool
+ "before": &tengo.UserFunction{
+ Name: "before",
+ Value: timesBefore,
+ }, // before(t time, u time) => bool
+ "time_year": &tengo.UserFunction{
+ Name: "time_year",
+ Value: timesTimeYear,
+ }, // time_year(time) => int
+ "time_month": &tengo.UserFunction{
+ Name: "time_month",
+ Value: timesTimeMonth,
+ }, // time_month(time) => int
+ "time_day": &tengo.UserFunction{
+ Name: "time_day",
+ Value: timesTimeDay,
+ }, // time_day(time) => int
+ "time_weekday": &tengo.UserFunction{
+ Name: "time_weekday",
+ Value: timesTimeWeekday,
+ }, // time_weekday(time) => int
+ "time_hour": &tengo.UserFunction{
+ Name: "time_hour",
+ Value: timesTimeHour,
+ }, // time_hour(time) => int
+ "time_minute": &tengo.UserFunction{
+ Name: "time_minute",
+ Value: timesTimeMinute,
+ }, // time_minute(time) => int
+ "time_second": &tengo.UserFunction{
+ Name: "time_second",
+ Value: timesTimeSecond,
+ }, // time_second(time) => int
+ "time_nanosecond": &tengo.UserFunction{
+ Name: "time_nanosecond",
+ Value: timesTimeNanosecond,
+ }, // time_nanosecond(time) => int
+ "time_unix": &tengo.UserFunction{
+ Name: "time_unix",
+ Value: timesTimeUnix,
+ }, // time_unix(time) => int
+ "time_unix_nano": &tengo.UserFunction{
+ Name: "time_unix_nano",
+ Value: timesTimeUnixNano,
+ }, // time_unix_nano(time) => int
+ "time_format": &tengo.UserFunction{
+ Name: "time_format",
+ Value: timesTimeFormat,
+ }, // time_format(time, format) => string
+ "time_location": &tengo.UserFunction{
+ Name: "time_location",
+ Value: timesTimeLocation,
+ }, // time_location(time) => string
+ "time_string": &tengo.UserFunction{
+ Name: "time_string",
+ Value: timesTimeString,
+ }, // time_string(time) => string
+ "is_zero": &tengo.UserFunction{
+ Name: "is_zero",
+ Value: timesIsZero,
+ }, // is_zero(time) => bool
+ "to_local": &tengo.UserFunction{
+ Name: "to_local",
+ Value: timesToLocal,
+ }, // to_local(time) => time
+ "to_utc": &tengo.UserFunction{
+ Name: "to_utc",
+ Value: timesToUTC,
+ }, // to_utc(time) => time
+}
+
+func timesSleep(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ i1, ok := tengo.ToInt64(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ time.Sleep(time.Duration(i1))
+ ret = tengo.UndefinedValue
+
+ return
+}
+
+func timesParseDuration(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ dur, err := time.ParseDuration(s1)
+ if err != nil {
+ ret = wrapError(err)
+ return
+ }
+
+ ret = &tengo.Int{Value: int64(dur)}
+
+ return
+}
+
+func timesSince(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Int{Value: int64(time.Since(t1))}
+
+ return
+}
+
+func timesUntil(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Int{Value: int64(time.Until(t1))}
+
+ return
+}
+
+func timesDurationHours(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ i1, ok := tengo.ToInt64(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Float{Value: time.Duration(i1).Hours()}
+
+ return
+}
+
+func timesDurationMinutes(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ i1, ok := tengo.ToInt64(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Float{Value: time.Duration(i1).Minutes()}
+
+ return
+}
+
+func timesDurationNanoseconds(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ i1, ok := tengo.ToInt64(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Int{Value: time.Duration(i1).Nanoseconds()}
+
+ return
+}
+
+func timesDurationSeconds(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ i1, ok := tengo.ToInt64(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Float{Value: time.Duration(i1).Seconds()}
+
+ return
+}
+
+func timesDurationString(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ i1, ok := tengo.ToInt64(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.String{Value: time.Duration(i1).String()}
+
+ return
+}
+
+func timesMonthString(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ i1, ok := tengo.ToInt64(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.String{Value: time.Month(i1).String()}
+
+ return
+}
+
+func timesDate(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+) {
+ if len(args) != 7 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ i1, ok := tengo.ToInt(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+ i3, ok := tengo.ToInt(args[2])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "int(compatible)",
+ Found: args[2].TypeName(),
+ }
+ return
+ }
+ i4, ok := tengo.ToInt(args[3])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "fourth",
+ Expected: "int(compatible)",
+ Found: args[3].TypeName(),
+ }
+ return
+ }
+ i5, ok := tengo.ToInt(args[4])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "fifth",
+ Expected: "int(compatible)",
+ Found: args[4].TypeName(),
+ }
+ return
+ }
+ i6, ok := tengo.ToInt(args[5])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "sixth",
+ Expected: "int(compatible)",
+ Found: args[5].TypeName(),
+ }
+ return
+ }
+ i7, ok := tengo.ToInt(args[6])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "seventh",
+ Expected: "int(compatible)",
+ Found: args[6].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Time{
+ Value: time.Date(i1,
+ time.Month(i2), i3, i4, i5, i6, i7, time.Now().Location()),
+ }
+
+ return
+}
+
+func timesNow(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 0 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ ret = &tengo.Time{Value: time.Now()}
+
+ return
+}
+
+func timesParse(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ s1, ok := tengo.ToString(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "string(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ parsed, err := time.Parse(s1, s2)
+ if err != nil {
+ ret = wrapError(err)
+ return
+ }
+
+ ret = &tengo.Time{Value: parsed}
+
+ return
+}
+
+func timesUnix(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ i1, ok := tengo.ToInt64(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "int(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ i2, ok := tengo.ToInt64(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Time{Value: time.Unix(i1, i2)}
+
+ return
+}
+
+func timesAdd(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ i2, ok := tengo.ToInt64(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Time{Value: t1.Add(time.Duration(i2))}
+
+ return
+}
+
+func timesSub(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ t2, ok := tengo.ToTime(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "time(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Int{Value: int64(t1.Sub(t2))}
+
+ return
+}
+
+func timesAddDate(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 4 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ i2, ok := tengo.ToInt(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "int(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ i3, ok := tengo.ToInt(args[2])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "third",
+ Expected: "int(compatible)",
+ Found: args[2].TypeName(),
+ }
+ return
+ }
+
+ i4, ok := tengo.ToInt(args[3])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "fourth",
+ Expected: "int(compatible)",
+ Found: args[3].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Time{Value: t1.AddDate(i2, i3, i4)}
+
+ return
+}
+
+func timesAfter(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ t2, ok := tengo.ToTime(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "time(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ if t1.After(t2) {
+ ret = tengo.TrueValue
+ } else {
+ ret = tengo.FalseValue
+ }
+
+ return
+}
+
+func timesBefore(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ t2, ok := tengo.ToTime(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ if t1.Before(t2) {
+ ret = tengo.TrueValue
+ } else {
+ ret = tengo.FalseValue
+ }
+
+ return
+}
+
+func timesTimeYear(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Int{Value: int64(t1.Year())}
+
+ return
+}
+
+func timesTimeMonth(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Int{Value: int64(t1.Month())}
+
+ return
+}
+
+func timesTimeDay(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Int{Value: int64(t1.Day())}
+
+ return
+}
+
+func timesTimeWeekday(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Int{Value: int64(t1.Weekday())}
+
+ return
+}
+
+func timesTimeHour(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Int{Value: int64(t1.Hour())}
+
+ return
+}
+
+func timesTimeMinute(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Int{Value: int64(t1.Minute())}
+
+ return
+}
+
+func timesTimeSecond(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Int{Value: int64(t1.Second())}
+
+ return
+}
+
+func timesTimeNanosecond(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Int{Value: int64(t1.Nanosecond())}
+
+ return
+}
+
+func timesTimeUnix(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Int{Value: t1.Unix()}
+
+ return
+}
+
+func timesTimeUnixNano(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Int{Value: t1.UnixNano()}
+
+ return
+}
+
+func timesTimeFormat(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 2 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ s2, ok := tengo.ToString(args[1])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "second",
+ Expected: "string(compatible)",
+ Found: args[1].TypeName(),
+ }
+ return
+ }
+
+ s := t1.Format(s2)
+ if len(s) > tengo.MaxStringLen {
+
+ return nil, tengo.ErrStringLimit
+ }
+
+ ret = &tengo.String{Value: s}
+
+ return
+}
+
+func timesIsZero(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ if t1.IsZero() {
+ ret = tengo.TrueValue
+ } else {
+ ret = tengo.FalseValue
+ }
+
+ return
+}
+
+func timesToLocal(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Time{Value: t1.Local()}
+
+ return
+}
+
+func timesToUTC(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.Time{Value: t1.UTC()}
+
+ return
+}
+
+func timesTimeLocation(args ...tengo.Object) (
+ ret tengo.Object,
+ err error,
+) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.String{Value: t1.Location().String()}
+
+ return
+}
+
+func timesTimeString(args ...tengo.Object) (ret tengo.Object, err error) {
+ if len(args) != 1 {
+ err = tengo.ErrWrongNumArguments
+ return
+ }
+
+ t1, ok := tengo.ToTime(args[0])
+ if !ok {
+ err = tengo.ErrInvalidArgumentType{
+ Name: "first",
+ Expected: "time(compatible)",
+ Found: args[0].TypeName(),
+ }
+ return
+ }
+
+ ret = &tengo.String{Value: t1.String()}
+
+ return
+}