github.com/MontFerret/ferret@v0.18.0/pkg/runtime/core/function.go (about) 1 package core 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 ) 8 9 const MaxArgs = 65536 10 11 type ( 12 Namespace interface { 13 Namespace(name string) Namespace 14 RegisterFunction(name string, fun Function) error 15 RegisterFunctions(funs *Functions) error 16 RegisteredFunctions() []string 17 RemoveFunction(name string) 18 } 19 ) 20 21 func ValidateArgs(args []Value, minimum, maximum int) error { 22 count := len(args) 23 24 if count < minimum || count > maximum { 25 return Error( 26 ErrInvalidArgumentNumber, 27 fmt.Sprintf( 28 "expected number of arguments %d-%d, but got %d", 29 minimum, 30 maximum, 31 len(args))) 32 } 33 34 return nil 35 } 36 37 type ( 38 // Functions is a container for functions. 39 Functions struct { 40 functions map[string]Function 41 } 42 43 // Function is a common interface for all functions of FQL. 44 Function = func(ctx context.Context, args ...Value) (Value, error) 45 ) 46 47 // NewFunctions returns new empty Functions. 48 func NewFunctions() *Functions { 49 return &Functions{ 50 functions: make(map[string]Function), 51 } 52 } 53 54 // NewFunctionsFromMap creates new Functions from map, where 55 // key is the name of the function and value is the function. 56 func NewFunctionsFromMap(funcs map[string]Function) *Functions { 57 fns := NewFunctions() 58 59 for name, fn := range funcs { 60 fns.Set(name, fn) 61 } 62 63 return fns 64 } 65 66 // Get returns the function with the given name. If the function 67 // does not exist it returns nil, false. 68 func (fns *Functions) Get(name string) (Function, bool) { 69 fn, exists := fns.functions[strings.ToUpper(name)] 70 return fn, exists 71 } 72 73 // Set sets the function with the given name. If the function 74 // with the such name already exists it will be overwritten. 75 func (fns *Functions) Set(name string, fn Function) { 76 // the preferred way to create Functions is NewFunctions. 77 // But just in case, if someone creates differently 78 if fns.functions == nil { 79 fns.functions = make(map[string]Function, 1) 80 } 81 82 fns.functions[strings.ToUpper(name)] = fn 83 } 84 85 // Unset delete the function with the given name. 86 func (fns *Functions) Unset(name string) { 87 delete(fns.functions, strings.ToUpper(name)) 88 } 89 90 // Names returns the names of the internal functions. 91 func (fns *Functions) Names() []string { 92 names := make([]string, 0, len(fns.functions)) 93 94 for name := range fns.functions { 95 names = append(names, name) 96 } 97 98 return names 99 }