Documentation
¶
Index ¶
- Variables
- func ExecuteAST(ctx context.Context, expr ast.Expr, value *model.Value, options *Options) (*model.Value, error)
- func ExecuteSelector(ctx context.Context, selectorStr string, value *model.Value, opts *Options) (*model.Value, error)
- func ExecutorDepth(ctx context.Context) int
- func ExecutorID(ctx context.Context) string
- func ExecutorPath(ctx context.Context) string
- func WithExecutorID(ctx context.Context, executorID string) context.Context
- type ArgsValidator
- type ExecuteOptionFn
- type Func
- type FuncCollection
- type FuncFn
- type Options
Constants ¶
This section is empty.
Variables ¶
var ( // DefaultFuncCollection is the default collection of functions that can be executed. DefaultFuncCollection = NewFuncCollection( FuncLen, FuncAdd, FuncToString, FuncToInt, FuncToFloat, FuncMerge, FuncReverse, FuncTypeOf, FuncMax, FuncMin, FuncIgnore, FuncBase64Encode, FuncBase64Decode, FuncParse, FuncReadFile, FuncHas, FuncGet, FuncContains, FuncSum, FuncJoin, FuncReplace, FuncKeys, FuncSplit, FuncToLower, FuncToUpper, FuncTrim, FuncTrimPrefix, FuncTrimSuffix, FuncStartsWith, FuncEndsWith, FuncIndexOf, FuncAbs, FuncFloor, FuncCeil, FuncRound, FuncAvg, FuncFlatten, FuncUnique, FuncFirst, FuncLast, FuncValues, FuncEntries, FuncFromEntries, FuncToBool, FuncStringify, ) )
var FuncAbs = NewFunc( "abs", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input *model.Value if len(args) == 1 { input = args[0] } else { input = data } if input.IsInt() { v, err := input.IntValue() if err != nil { return nil, fmt.Errorf("abs could not read int value: %w", err) } if v < 0 { v = -v } return model.NewIntValue(v), nil } v, err := input.FloatValue() if err != nil { return nil, fmt.Errorf("abs expects a numeric value: %w", err) } return model.NewFloatValue(math.Abs(v)), nil }, ValidateArgsMax(1), )
FuncAbs is a function that returns the absolute value of a number.
var FuncAdd = NewFunc( "add", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var foundInts, foundFloats int var intRes int64 var floatRes float64 for _, arg := range args { if arg.IsFloat() { foundFloats++ v, err := arg.FloatValue() if err != nil { return nil, fmt.Errorf("error getting float value: %w", err) } floatRes += v continue } if arg.IsInt() { foundInts++ v, err := arg.IntValue() if err != nil { return nil, fmt.Errorf("error getting int value: %w", err) } intRes += v continue } return nil, fmt.Errorf("expected int or float, got %s", arg.Type()) } if foundFloats > 0 { return model.NewFloatValue(floatRes + float64(intRes)), nil } return model.NewIntValue(intRes), nil }, ValidateArgsMin(1), )
FuncAdd is a function that adds the given values together.
var FuncAvg = NewFunc( "avg", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var sum float64 for _, arg := range args { if arg.IsInt() { intVal, err := arg.IntValue() if err != nil { return nil, err } sum += float64(intVal) continue } if arg.IsFloat() { floatVal, err := arg.FloatValue() if err != nil { return nil, err } sum += floatVal continue } return nil, fmt.Errorf("cannot average non-numeric value of type %s", arg.Type().String()) } return model.NewFloatValue(sum / float64(len(args))), nil }, ValidateArgsMin(1), )
FuncAvg is a function that returns the average of the given numbers. Always returns a float value.
var FuncBase64Decode = NewFunc( "base64d", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { arg := args[0] strVal, err := arg.StringValue() if err != nil { return nil, err } out, err := base64.StdEncoding.DecodeString(strVal) if err != nil { return nil, err } return model.NewStringValue(string(out)), nil }, ValidateArgsExactly(1), )
FuncBase64Decode base64 decodes the given value.
var FuncBase64Encode = NewFunc( "base64e", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { arg := args[0] strVal, err := arg.StringValue() if err != nil { return nil, err } out := base64.StdEncoding.EncodeToString([]byte(strVal)) return model.NewStringValue(out), nil }, ValidateArgsExactly(1), )
FuncBase64Encode base64 encodes the given value.
var FuncCeil = NewFunc( "ceil", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input *model.Value if len(args) == 1 { input = args[0] } else { input = data } if input.IsInt() { v, err := input.IntValue() if err != nil { return nil, fmt.Errorf("ceil could not read int value: %w", err) } return model.NewIntValue(v), nil } v, err := input.FloatValue() if err != nil { return nil, fmt.Errorf("ceil expects a numeric value: %w", err) } return model.NewIntValue(int64(math.Ceil(v))), nil }, ValidateArgsMax(1), )
FuncCeil is a function that returns the smallest integer value greater than or equal to the input.
var FuncContains = NewFunc( "contains", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var contains bool target := args[0] length, err := data.SliceLen() if err != nil { return nil, fmt.Errorf("error getting slice length: %w", err) } for i := 0; i < length; i++ { v, err := data.GetSliceIndex(i) if err != nil { return nil, fmt.Errorf("error getting slice index %d: %w", i, err) } matches, err := v.Equal(target) if err != nil { continue } matchesBool, err := matches.BoolValue() if err != nil { return nil, err } if matchesBool { contains = true break } } return model.NewBoolValue(contains), nil }, ValidateArgsExactly(1), )
FuncContains is a function that returns the highest number.
var FuncEndsWith = NewFunc( "endsWith", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input string var suffix string var err error if len(args) == 2 { input, err = args[0].StringValue() if err != nil { return nil, fmt.Errorf("endsWith expects a string as the first argument: %w", err) } suffix, err = args[1].StringValue() if err != nil { return nil, fmt.Errorf("endsWith expects a string suffix as the second argument: %w", err) } } else { input, err = data.StringValue() if err != nil { return nil, fmt.Errorf("endsWith expects data to be a string: %w", err) } suffix, err = args[0].StringValue() if err != nil { return nil, fmt.Errorf("endsWith expects a string suffix as the first argument: %w", err) } } return model.NewBoolValue(strings.HasSuffix(input, suffix)), nil }, ValidateArgsMinMax(1, 2), )
FuncEndsWith is a function that checks if a string ends with a given suffix.
var FuncEntries = NewFunc( "entries", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { if !data.IsMap() { return nil, fmt.Errorf("entries can only be used on maps, got %s", data.Type().String()) } res := model.NewSliceValue() if err := data.RangeMap(func(key string, value *model.Value) error { entry := model.NewMapValue() if err := entry.SetMapKey("key", model.NewStringValue(key)); err != nil { return err } if err := entry.SetMapKey("value", value); err != nil { return err } return res.Append(entry) }); err != nil { return nil, err } return res, nil }, ValidateArgsExactly(0), )
FuncEntries converts a map into an array of {key, value} objects.
var FuncFirst = NewFunc( "first", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input *model.Value if len(args) == 1 { input = args[0] } else { input = data } if !input.IsSlice() { return nil, fmt.Errorf("first expects an array, got %s", input.Type().String()) } length, err := input.SliceLen() if err != nil { return nil, err } if length == 0 { return model.NewNullValue(), nil } return input.GetSliceIndex(0) }, ValidateArgsMax(1), )
FuncFirst is a function that returns the first element of an array.
var FuncFlatten = NewFunc( "flatten", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input *model.Value if len(args) == 1 { input = args[0] } else { input = data } if !input.IsSlice() { return nil, fmt.Errorf("flatten expects an array, got %s", input.Type().String()) } res := model.NewSliceValue() if err := input.RangeSlice(func(i int, value *model.Value) error { if value.IsSlice() { return value.RangeSlice(func(j int, inner *model.Value) error { return res.Append(inner) }) } return res.Append(value) }); err != nil { return nil, err } return res, nil }, ValidateArgsMax(1), )
FuncFlatten is a function that flattens a nested array by one level.
var FuncFloor = NewFunc( "floor", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input *model.Value if len(args) == 1 { input = args[0] } else { input = data } if input.IsInt() { v, err := input.IntValue() if err != nil { return nil, fmt.Errorf("floor could not read int value: %w", err) } return model.NewIntValue(v), nil } v, err := input.FloatValue() if err != nil { return nil, fmt.Errorf("floor expects a numeric value: %w", err) } return model.NewIntValue(int64(math.Floor(v))), nil }, ValidateArgsMax(1), )
FuncFloor is a function that returns the largest integer value less than or equal to the input.
var FuncFromEntries = NewFunc( "fromEntries", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input *model.Value if len(args) == 1 { input = args[0] } else { input = data } if !input.IsSlice() { return nil, fmt.Errorf("fromEntries expects an array, got %s", input.Type().String()) } res := model.NewMapValue() if err := input.RangeSlice(func(i int, entry *model.Value) error { if !entry.IsMap() { return fmt.Errorf("fromEntries expects each element to be an object, got %s at index %d", entry.Type().String(), i) } keyVal, err := entry.GetMapKey("key") if err != nil { return fmt.Errorf("fromEntries expects each element to have a \"key\" field: %w", err) } key, err := keyVal.StringValue() if err != nil { return fmt.Errorf("fromEntries expects \"key\" to be a string: %w", err) } value, err := entry.GetMapKey("value") if err != nil { return fmt.Errorf("fromEntries expects each element to have a \"value\" field: %w", err) } return res.SetMapKey(key, value) }); err != nil { return nil, err } return res, nil }, ValidateArgsMax(1), )
FuncFromEntries converts an array of {key, value} objects into a map.
var FuncGet = NewFunc( "get", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { arg := args[0] switch arg.Type() { case model.TypeInt: index, err := arg.IntValue() if err != nil { return nil, err } return data.GetSliceIndex(int(index)) case model.TypeString: key, err := arg.StringValue() if err != nil { return nil, err } return data.GetMapKey(key) default: return nil, fmt.Errorf("get expects string or int argument") } }, ValidateArgsExactly(1), )
FuncGet is a function returns the value at the given key/index.
var FuncHas = NewFunc( "has", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { arg := args[0] switch arg.Type() { case model.TypeInt: if data.Type() != model.TypeSlice { return model.NewBoolValue(false), nil } index, err := arg.IntValue() if err != nil { return nil, err } sliceLen, err := data.SliceLen() if err != nil { return nil, err } return model.NewBoolValue(index >= 0 && index < int64(sliceLen)), nil case model.TypeString: if data.Type() != model.TypeMap { return model.NewBoolValue(false), nil } key, err := arg.StringValue() if err != nil { return nil, err } exists, err := data.MapKeyExists(key) if err != nil { return nil, err } return model.NewBoolValue(exists), nil default: return nil, fmt.Errorf("has expects string or int argument") } }, ValidateArgsMin(1), )
FuncHas is a function that true or false if the input has the given key/index.
var FuncIgnore = NewFunc( "ignore", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { data.MarkAsIgnore() return data, nil }, ValidateArgsExactly(0), )
FuncIgnore is a function that ignores the value, causing it to be rejected from a branch.
var FuncIndexOf = NewFunc( "indexOf", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input string var substr string var err error if len(args) == 2 { input, err = args[0].StringValue() if err != nil { return nil, fmt.Errorf("indexOf expects a string as the first argument: %w", err) } substr, err = args[1].StringValue() if err != nil { return nil, fmt.Errorf("indexOf expects a string substring as the second argument: %w", err) } } else { input, err = data.StringValue() if err != nil { return nil, fmt.Errorf("indexOf expects data to be a string: %w", err) } substr, err = args[0].StringValue() if err != nil { return nil, fmt.Errorf("indexOf expects a string substring as the first argument: %w", err) } } return model.NewIntValue(int64(strings.Index(input, substr))), nil }, ValidateArgsMinMax(1, 2), )
FuncIndexOf is a function that returns the index of the first occurrence of a substring. Returns -1 if the substring is not found.
var FuncJoin = NewFunc( "join", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { separator, err := args[0].StringValue() if err != nil { return nil, fmt.Errorf("join expects a string separator as the first argument: %w", err) } var valuesToJoin []string if len(args) == 2 && args[1].IsSlice() { if err := args[1].RangeSlice(func(i int, value *model.Value) error { strVal, err := value.StringValue() if err != nil { return fmt.Errorf("could not read string value of index %d: %w", i, err) } valuesToJoin = append(valuesToJoin, strVal) return nil }); err != nil { return nil, err } } else if len(args) > 1 { for i := 1; i < len(args); i++ { strVal, err := args[i].StringValue() if err != nil { return nil, fmt.Errorf("could not read string value of argument index %d: %w", i, err) } valuesToJoin = append(valuesToJoin, strVal) } } else { if err := data.RangeSlice(func(i int, value *model.Value) error { strVal, err := value.StringValue() if err != nil { return fmt.Errorf("could not read string value of index %d: %w", i, err) } valuesToJoin = append(valuesToJoin, strVal) return nil }); err != nil { return nil, err } } joined := strings.Join(valuesToJoin, separator) return model.NewStringValue(joined), nil }, ValidateArgsMin(1), )
FuncJoin is a function that joins the given data or args to a string.
var FuncKeys = NewFunc( "keys", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { switch data.Type() { case model.TypeMap: keys, err := data.MapKeys() if err != nil { return nil, err } res := model.NewSliceValue() for _, key := range keys { if err := res.Append(model.NewStringValue(key)); err != nil { return nil, err } } return res, nil case model.TypeSlice: len, err := data.SliceLen() if err != nil { return nil, err } res := model.NewSliceValue() for i := 0; i < len; i++ { if err := res.Append(model.NewIntValue(int64(i))); err != nil { return nil, err } } return res, nil default: return nil, fmt.Errorf("keys can only be used on maps and slices") } }, ValidateArgsExactly(0), )
FuncKeys returns the keys of a map or the indices of a slice.
var FuncLast = NewFunc( "last", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input *model.Value if len(args) == 1 { input = args[0] } else { input = data } if !input.IsSlice() { return nil, fmt.Errorf("last expects an array, got %s", input.Type().String()) } length, err := input.SliceLen() if err != nil { return nil, err } if length == 0 { return model.NewNullValue(), nil } return input.GetSliceIndex(length - 1) }, ValidateArgsMax(1), )
FuncLast is a function that returns the last element of an array.
var FuncLen = NewFunc( "len", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { arg := args[0] l, err := arg.Len() if err != nil { return nil, err } return model.NewIntValue(int64(l)), nil }, ValidateArgsExactly(1), )
FuncLen is a function that returns the length of the given value.
var FuncMax = NewFunc( "max", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { res := model.NewNullValue() for _, arg := range args { if res.IsNull() { res = arg continue } gt, err := arg.GreaterThan(res) if err != nil { return nil, err } gtBool, err := gt.BoolValue() if err != nil { return nil, err } if gtBool { res = arg } } return res, nil }, ValidateArgsMin(1), )
FuncMax is a function that returns the highest number.
var FuncMerge = NewFunc( "merge", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { if len(args) == 1 { return args[0], nil } expectedType := args[0].Type() switch expectedType { case model.TypeMap: break default: return nil, fmt.Errorf("merge expects a map, found %s", expectedType) } for _, a := range args { if a.Type() != expectedType { return nil, fmt.Errorf("merge expects all arguments to be of the same type. expected %s, got %s", expectedType.String(), a.Type().String()) } } base := model.NewMapValue() for i := 0; i < len(args); i++ { if err := deepMergeMap(base, args[i]); err != nil { return nil, fmt.Errorf("merge failed on arg %d: %w", i, err) } } return base, nil }, ValidateArgsMin(1), )
FuncMerge is a function that deep-merges two or more maps together.
var FuncMin = NewFunc( "min", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { res := model.NewNullValue() for _, arg := range args { if res.IsNull() { res = arg continue } lt, err := arg.LessThan(res) if err != nil { return nil, err } ltBool, err := lt.BoolValue() if err != nil { return nil, err } if ltBool { res = arg } } return res, nil }, ValidateArgsMin(1), )
FuncMin is a function that returns the smalled number.
var FuncParse = NewFunc( "parse", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var format parsing.Format var content []byte { strVal, err := args[0].StringValue() if err != nil { return nil, err } format = parsing.Format(strVal) } { strVal, err := args[1].StringValue() if err != nil { return nil, err } content = []byte(strVal) } reader, err := format.NewReader(parsing.DefaultReaderOptions()) if err != nil { return nil, err } doc, err := reader.Read(content) if err != nil { return nil, err } return doc, nil }, ValidateArgsExactly(2), )
FuncParse parses the given data at runtime.
var FuncReadFile = NewFunc( "readFile", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { filepath, err := args[0].StringValue() if err != nil { return nil, fmt.Errorf("readFile: %w", err) } f, err := os.Open(filepath) if err != nil { return nil, fmt.Errorf("readFile: %w", err) } defer func() { _ = f.Close() }() fileBytes, err := io.ReadAll(f) if err != nil { return nil, fmt.Errorf("readFile: %w", err) } return model.NewStringValue(string(fileBytes)), nil }, ValidateArgsExactly(1), )
FuncReadFile reads the given filepath at runtime.
var FuncReplace = NewFunc( "replace", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { inputData := data if len(args)%2 != 0 { inputData = args[0] args = args[1:] } argStrings := make([]string, len(args)) for i, arg := range args { s, err := arg.StringValue() if err != nil { return nil, err } argStrings[i] = s } replacer := strings.NewReplacer(argStrings...) inputString, err := inputData.StringValue() if err != nil { return nil, err } outputString := replacer.Replace(inputString) return model.NewStringValue(outputString), nil }, ValidateArgsMin(2), )
FuncReplace is a function that replaces all occurrences of a substring with another string.
var FuncReverse = NewFunc( "reverse", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { arg := args[0] switch arg.Type() { case model.TypeString: return arg.StringIndexRange(-1, 0) case model.TypeSlice: return arg.SliceIndexRange(-1, 0) default: return nil, fmt.Errorf("reverse expects a slice or string, got %s", arg.Type()) } }, ValidateArgsExactly(1), )
FuncReverse is a function that reverses the input.
var FuncRound = NewFunc( "round", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input *model.Value if len(args) == 1 { input = args[0] } else { input = data } if input.IsInt() { v, err := input.IntValue() if err != nil { return nil, fmt.Errorf("round could not read int value: %w", err) } return model.NewIntValue(v), nil } v, err := input.FloatValue() if err != nil { return nil, fmt.Errorf("round expects a numeric value: %w", err) } return model.NewIntValue(int64(math.Round(v))), nil }, ValidateArgsMax(1), )
FuncRound is a function that rounds a number to the nearest integer.
var FuncSplit = NewFunc( "split", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { separator, err := args[0].StringValue() if err != nil { return nil, fmt.Errorf("split expects a string separator as the first argument: %w", err) } var input string if len(args) == 2 { input, err = args[1].StringValue() if err != nil { return nil, fmt.Errorf("split expects a string as the second argument: %w", err) } } else { input, err = data.StringValue() if err != nil { return nil, fmt.Errorf("split expects data to be a string: %w", err) } } parts := strings.Split(input, separator) res := model.NewSliceValue() for _, part := range parts { if err := res.Append(model.NewStringValue(part)); err != nil { return nil, fmt.Errorf("could not append split result: %w", err) } } return res, nil }, ValidateArgsMinMax(1, 2), )
FuncSplit is a function that splits a string by a separator into an array.
var FuncStartsWith = NewFunc( "startsWith", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input string var prefix string var err error if len(args) == 2 { input, err = args[0].StringValue() if err != nil { return nil, fmt.Errorf("startsWith expects a string as the first argument: %w", err) } prefix, err = args[1].StringValue() if err != nil { return nil, fmt.Errorf("startsWith expects a string prefix as the second argument: %w", err) } } else { input, err = data.StringValue() if err != nil { return nil, fmt.Errorf("startsWith expects data to be a string: %w", err) } prefix, err = args[0].StringValue() if err != nil { return nil, fmt.Errorf("startsWith expects a string prefix as the first argument: %w", err) } } return model.NewBoolValue(strings.HasPrefix(input, prefix)), nil }, ValidateArgsMinMax(1, 2), )
FuncStartsWith is a function that checks if a string starts with a given prefix.
var FuncStringify = NewFunc( "stringify", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { formatStr, err := args[0].StringValue() if err != nil { return nil, err } format := parsing.Format(formatStr) input := data if len(args) == 2 { input = args[1] } opts := parsing.DefaultWriterOptions() opts.Compact = true writer, err := format.NewWriter(opts) if err != nil { return nil, err } b, err := writer.Write(input) if err != nil { return nil, err } b = bytes.TrimSuffix(b, []byte("\n")) return model.NewStringValue(string(b)), nil }, ValidateArgsMinMax(1, 2), )
FuncStringify serializes a structured value into a format string.
var FuncSum = NewFunc( "sum", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { returnType := model.TypeInt for _, arg := range args { if arg.IsInt() { continue } if arg.IsFloat() { returnType = model.TypeFloat break } return nil, fmt.Errorf("cannot sum non-numeric value of type %s", arg.Type().String()) } switch returnType { case model.TypeInt: var sum int64 for _, arg := range args { if arg.IsInt() { intVal, err := arg.IntValue() if err != nil { return nil, err } sum += intVal continue } floatVal, err := arg.FloatValue() if err != nil { return nil, err } sum += int64(floatVal) } return model.NewIntValue(sum), nil case model.TypeFloat: var sum float64 for _, arg := range args { if arg.IsInt() { intVal, err := arg.IntValue() if err != nil { return nil, err } sum += float64(intVal) continue } floatVal, err := arg.FloatValue() if err != nil { return nil, err } sum += floatVal } return model.NewFloatValue(sum), nil default: return nil, fmt.Errorf("unsupported return type %s", returnType.String()) } }, ValidateArgsMin(1), )
FuncSum is a function that returns the sum of the given numbers.
var FuncToBool = NewFunc( "toBool", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { switch args[0].Type() { case model.TypeBool: b, err := args[0].BoolValue() if err != nil { return nil, err } return model.NewBoolValue(b), nil case model.TypeString: s, err := args[0].StringValue() if err != nil { return nil, err } switch strings.ToLower(s) { case "true", "1", "yes": return model.NewBoolValue(true), nil case "false", "0", "no", "": return model.NewBoolValue(false), nil default: return nil, fmt.Errorf("cannot convert string %q to bool", s) } case model.TypeInt: i, err := args[0].IntValue() if err != nil { return nil, err } return model.NewBoolValue(i != 0), nil case model.TypeFloat: f, err := args[0].FloatValue() if err != nil { return nil, err } return model.NewBoolValue(f != 0), nil case model.TypeNull: return model.NewBoolValue(false), nil default: return nil, fmt.Errorf("cannot convert %s to bool", args[0].Type()) } }, ValidateArgsExactly(1), )
FuncToBool is a function that converts the given value to a bool.
var FuncToFloat = NewFunc( "toFloat", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { switch args[0].Type() { case model.TypeString: stringValue, err := args[0].StringValue() if err != nil { return nil, err } i, err := strconv.ParseFloat(stringValue, 64) if err != nil { return nil, err } return model.NewFloatValue(i), nil case model.TypeInt: i, err := args[0].IntValue() if err != nil { return nil, err } return model.NewFloatValue(float64(i)), nil case model.TypeFloat: return args[0], nil case model.TypeBool: i, err := args[0].BoolValue() if err != nil { return nil, err } if i { return model.NewFloatValue(1), nil } return model.NewFloatValue(0), nil default: return nil, fmt.Errorf("cannot convert %s to float", args[0].Type()) } }, ValidateArgsExactly(1), )
FuncToFloat is a function that converts the given value to a string.
var FuncToInt = NewFunc( "toInt", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { switch args[0].Type() { case model.TypeString: stringValue, err := args[0].StringValue() if err != nil { return nil, err } i, err := strconv.ParseInt(stringValue, 0, 64) if err != nil { return nil, err } return model.NewIntValue(i), nil case model.TypeInt: return args[0], nil case model.TypeFloat: i, err := args[0].FloatValue() if err != nil { return nil, err } return model.NewIntValue(int64(i)), nil case model.TypeBool: i, err := args[0].BoolValue() if err != nil { return nil, err } if i { return model.NewIntValue(1), nil } return model.NewIntValue(0), nil default: return nil, fmt.Errorf("cannot convert %s to int", args[0].Type()) } }, ValidateArgsExactly(1), )
FuncToInt is a function that converts the given value to a string.
var FuncToLower = NewFunc( "toLower", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input string var err error if len(args) == 1 { input, err = args[0].StringValue() if err != nil { return nil, fmt.Errorf("toLower expects a string argument: %w", err) } } else { input, err = data.StringValue() if err != nil { return nil, fmt.Errorf("toLower expects data to be a string: %w", err) } } return model.NewStringValue(strings.ToLower(input)), nil }, ValidateArgsMax(1), )
FuncToLower is a function that converts a string to lowercase.
var FuncToString = NewFunc( "toString", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { switch args[0].Type() { case model.TypeString: stringValue, err := args[0].StringValue() if err != nil { return nil, err } model.NewStringValue(stringValue) return args[0], nil case model.TypeInt: i, err := args[0].IntValue() if err != nil { return nil, err } return model.NewStringValue(fmt.Sprintf("%d", i)), nil case model.TypeFloat: i, err := args[0].FloatValue() if err != nil { return nil, err } return model.NewStringValue(fmt.Sprintf("%g", i)), nil case model.TypeBool: i, err := args[0].BoolValue() if err != nil { return nil, err } return model.NewStringValue(fmt.Sprintf("%v", i)), nil default: return nil, fmt.Errorf("cannot convert %s to string", args[0].Type()) } }, ValidateArgsExactly(1), )
FuncToString is a function that converts the given value to a string.
var FuncToUpper = NewFunc( "toUpper", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input string var err error if len(args) == 1 { input, err = args[0].StringValue() if err != nil { return nil, fmt.Errorf("toUpper expects a string argument: %w", err) } } else { input, err = data.StringValue() if err != nil { return nil, fmt.Errorf("toUpper expects data to be a string: %w", err) } } return model.NewStringValue(strings.ToUpper(input)), nil }, ValidateArgsMax(1), )
FuncToUpper is a function that converts a string to uppercase.
var FuncTrim = NewFunc( "trim", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input string var err error if len(args) == 1 { input, err = args[0].StringValue() if err != nil { return nil, fmt.Errorf("trim expects a string argument: %w", err) } } else { input, err = data.StringValue() if err != nil { return nil, fmt.Errorf("trim expects data to be a string: %w", err) } } return model.NewStringValue(strings.TrimSpace(input)), nil }, ValidateArgsMax(1), )
FuncTrim is a function that trims whitespace from both ends of a string.
var FuncTrimPrefix = NewFunc( "trimPrefix", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input string var prefix string var err error if len(args) == 2 { input, err = args[0].StringValue() if err != nil { return nil, fmt.Errorf("trimPrefix expects a string as the first argument: %w", err) } prefix, err = args[1].StringValue() if err != nil { return nil, fmt.Errorf("trimPrefix expects a string prefix as the second argument: %w", err) } } else { input, err = data.StringValue() if err != nil { return nil, fmt.Errorf("trimPrefix expects data to be a string: %w", err) } prefix, err = args[0].StringValue() if err != nil { return nil, fmt.Errorf("trimPrefix expects a string prefix as the first argument: %w", err) } } return model.NewStringValue(strings.TrimPrefix(input, prefix)), nil }, ValidateArgsMinMax(1, 2), )
FuncTrimPrefix is a function that trims a prefix from a string.
var FuncTrimSuffix = NewFunc( "trimSuffix", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input string var suffix string var err error if len(args) == 2 { input, err = args[0].StringValue() if err != nil { return nil, fmt.Errorf("trimSuffix expects a string as the first argument: %w", err) } suffix, err = args[1].StringValue() if err != nil { return nil, fmt.Errorf("trimSuffix expects a string suffix as the second argument: %w", err) } } else { input, err = data.StringValue() if err != nil { return nil, fmt.Errorf("trimSuffix expects data to be a string: %w", err) } suffix, err = args[0].StringValue() if err != nil { return nil, fmt.Errorf("trimSuffix expects a string suffix as the first argument: %w", err) } } return model.NewStringValue(strings.TrimSuffix(input, suffix)), nil }, ValidateArgsMinMax(1, 2), )
FuncTrimSuffix is a function that trims a suffix from a string.
var FuncTypeOf = NewFunc( "typeOf", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { return model.NewStringValue(args[0].Type().String()), nil }, ValidateArgsExactly(1), )
FuncTypeOf is a function that returns the type of the first argument as a string.
var FuncUnique = NewFunc( "unique", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { var input *model.Value if len(args) == 1 { input = args[0] } else { input = data } if !input.IsSlice() { return nil, fmt.Errorf("unique expects an array, got %s", input.Type().String()) } res := model.NewSliceValue() if err := input.RangeSlice(func(i int, value *model.Value) error { duplicate := false _ = res.RangeSlice(func(j int, existing *model.Value) error { equal, err := value.EqualTypeValue(existing) if err != nil { return nil } if equal { duplicate = true } return nil }) if !duplicate { return res.Append(value) } return nil }); err != nil { return nil, err } return res, nil }, ValidateArgsMax(1), )
FuncUnique is a function that removes duplicate values from an array.
var FuncValues = NewFunc( "values", func(ctx context.Context, data *model.Value, args model.Values) (*model.Value, error) { if !data.IsMap() { return nil, fmt.Errorf("values can only be used on maps, got %s", data.Type().String()) } res := model.NewSliceValue() if err := data.RangeMap(func(key string, value *model.Value) error { return res.Append(value) }); err != nil { return nil, err } return res, nil }, ValidateArgsExactly(0), )
FuncValues returns the values of a map as an array.
Functions ¶
func ExecuteAST ¶
func ExecuteAST(ctx context.Context, expr ast.Expr, value *model.Value, options *Options) (*model.Value, error)
ExecuteAST executes the given AST with the given input.
func ExecuteSelector ¶
func ExecuteSelector(ctx context.Context, selectorStr string, value *model.Value, opts *Options) (*model.Value, error)
ExecuteSelector parses the selector and executes the resulting AST with the given input.
func ExecutorDepth ¶
func ExecutorID ¶
func ExecutorPath ¶
Types ¶
type ArgsValidator ¶
ArgsValidator is a function that validates the arguments passed to a function.
func ValidateArgsExactly ¶
func ValidateArgsExactly(expected int) ArgsValidator
ValidateArgsExactly returns an ArgsValidator that validates that the number of arguments passed to a function is exactly the expected number.
func ValidateArgsMax ¶
func ValidateArgsMax(expected int) ArgsValidator
ValidateArgsMax returns an ArgsValidator that validates that the number of arguments passed to a function is at most the expected number.
func ValidateArgsMin ¶
func ValidateArgsMin(expected int) ArgsValidator
ValidateArgsMin returns an ArgsValidator that validates that the number of arguments passed to a function is at least the expected number.
func ValidateArgsMinMax ¶
func ValidateArgsMinMax(min int, max int) ArgsValidator
ValidateArgsMinMax returns an ArgsValidator that validates that the number of arguments passed to a function is between the min and max expected numbers.
type ExecuteOptionFn ¶
type ExecuteOptionFn func(*Options)
ExecuteOptionFn is a function that can be used to set options on the execution of the selector.
func WithFuncs ¶
func WithFuncs(fc FuncCollection) ExecuteOptionFn
WithFuncs sets the functions that can be used in the selector.
func WithUnstable ¶
func WithUnstable() ExecuteOptionFn
WithUnstable allows access to potentially unstable features.
func WithVariable ¶
func WithVariable(key string, val *model.Value) ExecuteOptionFn
WithVariable sets a variable for use in the selector.
func WithoutUnstable ¶
func WithoutUnstable() ExecuteOptionFn
WithoutUnstable disallows access to potentially unstable features.
type Func ¶
type Func struct {
// contains filtered or unexported fields
}
Func represents a function that can be executed.
type FuncCollection ¶
FuncCollection is a collection of functions that can be executed.
func NewFuncCollection ¶
func NewFuncCollection(funcs ...*Func) FuncCollection
NewFuncCollection creates a new FuncCollection with the given functions.
func (FuncCollection) Copy ¶
func (fc FuncCollection) Copy() FuncCollection
Copy returns a copy of the FuncCollection.
func (FuncCollection) Delete ¶
func (fc FuncCollection) Delete(names ...string) FuncCollection
Delete deletes the functions with the given names.
func (FuncCollection) Get ¶
func (fc FuncCollection) Get(name string) (FuncFn, bool)
Get returns the function with the given name.
func (FuncCollection) Register ¶
func (fc FuncCollection) Register(funcs ...*Func) FuncCollection
Register registers the given functions with the FuncCollection.
type Options ¶
type Options struct {
Funcs FuncCollection
Vars map[string]*model.Value
Unstable bool
}
Options contains the options for the execution of the selector.
func NewOptions ¶
func NewOptions(opts ...ExecuteOptionFn) *Options
NewOptions creates a new Options struct with the given options.
Source Files
¶
- context.go
- execute.go
- execute_all.go
- execute_any.go
- execute_array.go
- execute_assign.go
- execute_binary.go
- execute_branch.go
- execute_conditional.go
- execute_count.go
- execute_each.go
- execute_filter.go
- execute_func.go
- execute_literal.go
- execute_map.go
- execute_object.go
- execute_recursive_descent.go
- execute_search.go
- execute_sort_by.go
- execute_spread.go
- execute_unary.go
- func.go
- func_abs.go
- func_add.go
- func_avg.go
- func_base64.go
- func_ceil.go
- func_contains.go
- func_ends_with.go
- func_entries.go
- func_first.go
- func_flatten.go
- func_floor.go
- func_get.go
- func_has.go
- func_ignore.go
- func_index_of.go
- func_join.go
- func_keys.go
- func_last.go
- func_len.go
- func_max.go
- func_merge.go
- func_min.go
- func_parse.go
- func_readfile.go
- func_replace.go
- func_reverse.go
- func_round.go
- func_split.go
- func_starts_with.go
- func_stringify.go
- func_sum.go
- func_to_bool.go
- func_to_float.go
- func_to_int.go
- func_to_lower.go
- func_to_string.go
- func_to_upper.go
- func_trim.go
- func_type_of.go
- func_unique.go
- func_values.go
- options.go