github.com/MontFerret/ferret@v0.18.0/examples/extensible/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "os" 8 "strings" 9 10 "github.com/MontFerret/ferret/pkg/compiler" 11 "github.com/MontFerret/ferret/pkg/runtime/core" 12 "github.com/MontFerret/ferret/pkg/runtime/values" 13 "github.com/MontFerret/ferret/pkg/runtime/values/types" 14 ) 15 16 func main() { 17 strs, err := getStrings() 18 19 if err != nil { 20 fmt.Println(err) 21 os.Exit(1) 22 } 23 24 for _, str := range strs { 25 fmt.Println(str) 26 } 27 } 28 29 func getStrings() ([]string, error) { 30 // function implements is a type of a function that ferret supports as a runtime function 31 transform := func(ctx context.Context, args ...core.Value) (core.Value, error) { 32 // it's just a helper function which helps to validate a number of passed args 33 err := core.ValidateArgs(args, 1, 1) 34 35 if err != nil { 36 // it's recommended to return built-in None type, instead of nil 37 return values.None, err 38 } 39 40 // this is another helper functions allowing to do type validation 41 err = core.ValidateType(args[0], types.String) 42 43 if err != nil { 44 return values.None, err 45 } 46 47 // cast to built-in string type 48 str := args[0].(values.String) 49 50 return values.NewString(strings.ToUpper(str.String() + "_ferret")), nil 51 } 52 53 query := ` 54 FOR el IN ["foo", "bar", "qaz"] 55 // conventionally all functions are registered in upper case 56 RETURN TRANSFORM(el) 57 ` 58 59 comp := compiler.New() 60 61 if err := comp.RegisterFunction("transform", transform); err != nil { 62 return nil, err 63 } 64 65 program, err := comp.Compile(query) 66 67 if err != nil { 68 return nil, err 69 } 70 71 out, err := program.Run(context.Background()) 72 73 if err != nil { 74 return nil, err 75 } 76 77 res := make([]string, 0, 3) 78 79 err = json.Unmarshal(out, &res) 80 81 if err != nil { 82 return nil, err 83 } 84 85 return res, nil 86 }