1
0
mirror of https://github.com/MontFerret/ferret.git synced 2024-12-16 11:37:36 +02:00
ferret/pkg/runtime/core/function.go
2019-10-15 21:06:48 +03:00

100 lines
2.2 KiB
Go

package core
import (
"context"
"fmt"
"strings"
)
const MaxArgs = 65536
type (
Namespace interface {
Namespace(name string) Namespace
RegisterFunction(name string, fun Function) error
RegisterFunctions(funs *Functions) error
RegisteredFunctions() []string
RemoveFunction(name string)
}
)
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)))
}
return nil
}
type (
// Functions is a container for functions.
Functions struct {
functions map[string]Function
}
// Function is a common interface for all functions of FQL.
Function = func(ctx context.Context, args ...Value) (Value, error)
)
// NewFunctions returns new empty Functions.
func NewFunctions() *Functions {
return &Functions{
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)
}
return fns
}
// Get returns the function with the given name. If the function
// does not exist it returns nil, false.
func (fns *Functions) Get(name string) (Function, bool) {
fn, exists := fns.functions[strings.ToUpper(name)]
return fn, exists
}
// Set sets the function with the given name. If the function
// with the such name already exists it will be overwritten.
func (fns *Functions) Set(name string, fn Function) {
// the preferred way to create Functions is NewFunctions.
// But just in case, if someone creates differently
if fns.functions == nil {
fns.functions = make(map[string]Function, 1)
}
fns.functions[strings.ToUpper(name)] = fn
}
// Unset delete the function with the given name.
func (fns *Functions) Unset(name string) {
delete(fns.functions, strings.ToUpper(name))
}
// Names returns the names of the internal functions.
func (fns *Functions) Names() []string {
names := make([]string, 0, len(fns.functions))
for name := range fns.functions {
names = append(names, name)
}
return names
}