2018-09-18 22:42:38 +02:00
|
|
|
package core
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
2019-10-14 20:47:31 +02:00
|
|
|
"strings"
|
2018-09-18 22:42:38 +02:00
|
|
|
)
|
|
|
|
|
2018-09-22 02:36:33 +02:00
|
|
|
const MaxArgs = 65536
|
|
|
|
|
2019-07-22 23:21:20 +02:00
|
|
|
type (
|
|
|
|
Namespace interface {
|
|
|
|
Namespace(name string) Namespace
|
|
|
|
RegisterFunction(name string, fun Function) error
|
2019-10-15 20:06:48 +02:00
|
|
|
RegisterFunctions(funs *Functions) error
|
2019-07-22 23:21:20 +02:00
|
|
|
RegisteredFunctions() []string
|
|
|
|
RemoveFunction(name string)
|
|
|
|
}
|
|
|
|
)
|
2018-09-18 22:42:38 +02:00
|
|
|
|
2018-09-22 02:36:33 +02:00
|
|
|
func ValidateArgs(args []Value, minimum, maximum int) error {
|
|
|
|
count := len(args)
|
|
|
|
|
|
|
|
if count < minimum || count > maximum {
|
|
|
|
return Error(
|
|
|
|
ErrInvalidArgumentNumber,
|
|
|
|
fmt.Sprintf(
|
|
|
|
"expected number of arguments %d-%d, but got %d",
|
|
|
|
minimum,
|
|
|
|
maximum,
|
|
|
|
len(args)))
|
2018-09-18 22:42:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2019-10-14 20:47:31 +02:00
|
|
|
|
|
|
|
type (
|
2019-10-15 10:40:36 +02:00
|
|
|
// Functions is a container for functions.
|
|
|
|
Functions struct {
|
2019-10-15 20:06:48 +02:00
|
|
|
functions map[string]Function
|
2019-10-15 10:40:36 +02:00
|
|
|
}
|
|
|
|
|
2019-10-14 20:47:31 +02:00
|
|
|
// Function is a common interface for all functions of FQL.
|
|
|
|
Function = func(ctx context.Context, args ...Value) (Value, error)
|
|
|
|
)
|
|
|
|
|
2019-10-15 10:40:36 +02:00
|
|
|
// NewFunctions returns new empty Functions.
|
2019-10-15 11:04:04 +02:00
|
|
|
func NewFunctions() *Functions {
|
|
|
|
return &Functions{
|
2019-10-15 20:06:48 +02:00
|
|
|
functions: make(map[string]Function),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewFunctionsFromMap creates new Functions from map, where
|
|
|
|
// key is the name of the function and value is the function.
|
|
|
|
func NewFunctionsFromMap(funcs map[string]Function) *Functions {
|
|
|
|
fns := NewFunctions()
|
|
|
|
|
|
|
|
for name, fn := range funcs {
|
|
|
|
fns.Set(name, fn)
|
2019-10-15 10:40:36 +02:00
|
|
|
}
|
2019-10-15 20:06:48 +02:00
|
|
|
|
|
|
|
return fns
|
2019-10-15 10:40:36 +02:00
|
|
|
}
|
|
|
|
|
2019-10-14 20:47:31 +02:00
|
|
|
// Get returns the function with the given name. If the function
|
|
|
|
// does not exist it returns nil, false.
|
2019-10-15 11:04:04 +02:00
|
|
|
func (fns *Functions) Get(name string) (Function, bool) {
|
2019-10-15 10:40:36 +02:00
|
|
|
fn, exists := fns.functions[strings.ToUpper(name)]
|
2019-10-14 20:47:31 +02:00
|
|
|
return fn, exists
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set sets the function with the given name. If the function
|
|
|
|
// with the such name already exists it will be overwritten.
|
2019-10-15 11:04:04 +02:00
|
|
|
func (fns *Functions) Set(name string, fn Function) {
|
2019-10-15 10:40:36 +02:00
|
|
|
// the preferred way to create Functions is NewFunctions.
|
|
|
|
// But just in case, if someone creates differently
|
|
|
|
if fns.functions == nil {
|
2019-10-15 20:06:48 +02:00
|
|
|
fns.functions = make(map[string]Function, 1)
|
2019-10-15 10:40:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fns.functions[strings.ToUpper(name)] = fn
|
2019-10-14 20:47:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Unset delete the function with the given name.
|
2019-10-15 11:04:04 +02:00
|
|
|
func (fns *Functions) Unset(name string) {
|
2019-10-15 10:40:36 +02:00
|
|
|
delete(fns.functions, strings.ToUpper(name))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Names returns the names of the internal functions.
|
2019-10-15 11:04:04 +02:00
|
|
|
func (fns *Functions) Names() []string {
|
2019-10-15 10:40:36 +02:00
|
|
|
names := make([]string, 0, len(fns.functions))
|
|
|
|
|
|
|
|
for name := range fns.functions {
|
|
|
|
names = append(names, name)
|
|
|
|
}
|
|
|
|
|
|
|
|
return names
|
2019-10-14 20:47:31 +02:00
|
|
|
}
|