Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow dicts to be passed in as keyword args. #109

Merged
merged 2 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions aliases.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"

"github.com/Velocidex/ordereddict"
"www.velocidex.com/golang/vfilter/arg_parser"
"www.velocidex.com/golang/vfilter/functions"
"www.velocidex.com/golang/vfilter/plugins"
"www.velocidex.com/golang/vfilter/scope"
Expand Down Expand Up @@ -40,10 +39,6 @@ func NewScope() types.Scope {
return scope.NewScope()
}

func ExtractArgs(scope types.Scope, args *ordereddict.Dict, value interface{}) error {
return arg_parser.ExtractArgs(scope, args, value)
}

func RowToDict(
ctx context.Context,
scope types.Scope, row types.Row) *ordereddict.Dict {
Expand Down
38 changes: 23 additions & 15 deletions arg_parser/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (

// And parse the struct using this function:
// myarg := &MyArgs{}
// err := vfilter.ExtractArgs(scope, args, myarg)
// err := vfilter.ExtractArgsWithContext(ctx, scope, args, myarg)

// We will raise an error if a required field is missing or has the
// wrong type of args.
Expand All @@ -33,26 +33,34 @@ import (
// field must be exported (i.e. name begins with cap) and it must have
// vfilter tags.

// Deprecate this in favor of ExtractArgsWithContext
func ExtractArgs(scope types.Scope, args *ordereddict.Dict, target interface{}) error {
v := reflect.ValueOf(target)
if v.Type().Kind() == reflect.Ptr {
v = v.Elem()
}
// Allow the caller to pass args explicitly- this is similar to
// Python's ** notation:
// LET d = lazy_dict(a={....})
// SELECT * FROM plugin(`**`=d)
func NormalizeArgs(args *ordereddict.Dict) *ordereddict.Dict {
alt_args_any, pres := args.Get("**")
if pres {
lazy_arg, ok := alt_args_any.(types.LazyExpr)
if ok {
ctx := context.Background()
alt_args_any = lazy_arg.Reduce(ctx)
}

parser, err := GetParser(v)
if err != nil {
scope.Explainer().ParseArgs(args, target, err)
return err
alt_args, ok := alt_args_any.(*ordereddict.Dict)
if ok {
return alt_args
}
}

err = parser.Parse(context.Background(), scope, args, v)
scope.Explainer().ParseArgs(args, target, err)
return err
return args
}

func ExtractArgsWithContext(
ctx context.Context, scope types.Scope, args *ordereddict.Dict, target interface{}) error {
ctx context.Context, scope types.Scope,
args *ordereddict.Dict, target interface{}) error {

args = NormalizeArgs(args)

v := reflect.ValueOf(target)
if v.Type().Kind() == reflect.Ptr {
v = v.Elem()
Expand Down
2 changes: 1 addition & 1 deletion arg_parser/args_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ type argFunc struct{}

func (self argFunc) Call(ctx context.Context, scope types.Scope, args *ordereddict.Dict) types.Any {
arg := argFuncArgs{}
err := arg_parser.ExtractArgs(scope, args, &arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, &arg)
if err != nil {
result := ordereddict.NewDict().Set("ParseError", err.Error())
return result
Expand Down
2 changes: 1 addition & 1 deletion arg_parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ func BuildParser(v reflect.Value) (*Parser, error) {
t := v.Type()

if t.Kind() != reflect.Struct {
return nil, errors.New("Only structs can be set with ExtractArgs()")
return nil, errors.New("Only structs can be set with ExtractArgsWithContext()")
}

result := &Parser{}
Expand Down
10 changes: 5 additions & 5 deletions functions/aggregates.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func (self _CountFunction) Call(
scope types.Scope,
args *ordereddict.Dict) types.Any {
arg := &_CountFunctionArgs{}
err := arg_parser.ExtractArgs(scope, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
if err != nil {
scope.Log("count: %s", err.Error())
return types.Null{}
Expand Down Expand Up @@ -170,7 +170,7 @@ func (self _SumFunction) Call(
scope types.Scope,
args *ordereddict.Dict) types.Any {
arg := &_SumFunctionArgs{}
err := arg_parser.ExtractArgs(scope, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
if err != nil {
scope.Log("sum: %s", err.Error())
return types.Null{}
Expand Down Expand Up @@ -224,7 +224,7 @@ func (self _MinFunction) Call(
args *ordereddict.Dict) types.Any {
arg := &_MinFunctionArgs{}

err := arg_parser.ExtractArgs(scope, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
if err != nil {
scope.Log("min: %s", err.Error())
return types.Null{}
Expand Down Expand Up @@ -267,7 +267,7 @@ func (self _MaxFunction) Call(
scope types.Scope,
args *ordereddict.Dict) types.Any {
arg := &_MinFunctionArgs{}
err := arg_parser.ExtractArgs(scope, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
if err != nil {
scope.Log("min: %s", err.Error())
return types.Null{}
Expand Down Expand Up @@ -314,7 +314,7 @@ func (self _EnumerateFunction) Call(
scope types.Scope,
args *ordereddict.Dict) types.Any {
arg := &_EnumeateFunctionArgs{}
err := arg_parser.ExtractArgs(scope, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
if err != nil {
scope.Log("enumerate: %s", err.Error())
return types.Null{}
Expand Down
2 changes: 1 addition & 1 deletion functions/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (self FormatFunction) Call(ctx context.Context,
scope types.Scope,
args *ordereddict.Dict) types.Any {
arg := &FormatArgs{}
err := arg_parser.ExtractArgs(scope, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
if err != nil {
scope.Log("format: %v", err)
return false
Expand Down
10 changes: 5 additions & 5 deletions functions/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (self _Timestamp) Info(scope types.Scope, type_map *types.TypeMap) *types.F

func (self _Timestamp) Call(ctx context.Context, scope types.Scope, args *ordereddict.Dict) types.Any {
arg := &_TimestampArg{}
err := arg_parser.ExtractArgs(scope, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
if err != nil {
scope.Log("timestamp: %s", err.Error())
return types.Null{}
Expand Down Expand Up @@ -88,7 +88,7 @@ func (self _SplitFunction) Info(scope types.Scope, type_map *types.TypeMap) *typ

func (self _SplitFunction) Call(ctx context.Context, scope types.Scope, args *ordereddict.Dict) types.Any {
arg := &_SplitFunctionArgs{}
err := arg_parser.ExtractArgs(scope, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
if err != nil {
scope.Log("split: %s", err.Error())
return types.Null{}
Expand Down Expand Up @@ -129,7 +129,7 @@ func (self _GetFunction) Call(
scope types.Scope,
args *ordereddict.Dict) types.Any {
arg := &_GetFunctionArgs{}
err := arg_parser.ExtractArgs(scope, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
if err != nil {
scope.Log("get: %s", err.Error())
return types.Null{}
Expand Down Expand Up @@ -183,7 +183,7 @@ func (self _EncodeFunction) Call(
scope types.Scope,
args *ordereddict.Dict) types.Any {
arg := &_EncodeFunctionArgs{}
err := arg_parser.ExtractArgs(scope, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
if err != nil {
scope.Log("hex: %s", err.Error())
return types.Null{}
Expand Down Expand Up @@ -236,7 +236,7 @@ func (self LenFunction) Call(ctx context.Context,
scope types.Scope,
args *ordereddict.Dict) types.Any {
arg := &LenFunctionArgs{}
err := arg_parser.ExtractArgs(scope, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
if err != nil {
scope.Log("len: %s", err.Error())
return &types.Null{}
Expand Down
2 changes: 1 addition & 1 deletion functions/if.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (self _IfFunction) Call(
args *ordereddict.Dict) types.Any {

arg := &_IfFunctionArgs{}
err := arg_parser.ExtractArgs(scope, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
if err != nil {
scope.Log("if: %v", err)
return types.Null{}
Expand Down
4 changes: 2 additions & 2 deletions lazy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (self *LazyPlugin) Call(
defer close(output_chan)

arg := LazyPluginArgs{}
err := arg_parser.ExtractArgs(scope, args, &arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, &arg)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -96,7 +96,7 @@ func (self *LazyDictPlugin) Call(
defer close(output_chan)

arg := LazyPluginArgs{}
err := arg_parser.ExtractArgs(scope, args, &arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, &arg)
if err != nil {
panic(err)
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/flatten.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (self _FlattenPluginImpl) Call(ctx context.Context,
defer close(output_chan)

arg := _FlattenPluginImplArgs{}
err := arg_parser.ExtractArgs(scope, args, &arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, &arg)
if err != nil {
scope.Log("flatten: %v", err)
return
Expand Down
2 changes: 1 addition & 1 deletion plugins/foreach.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (self _ForeachPluginImpl) Call(ctx context.Context,
defer close(output_chan)

arg := _ForeachPluginImplArgs{}
err := arg_parser.ExtractArgs(scope, args, &arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, &arg)
if err != nil {
scope.Log("foreach: %v", err)
return
Expand Down
2 changes: 1 addition & 1 deletion plugins/if.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (self _IfPlugin) Call(
output_chan := make(chan types.Row)

arg := &_IfPluginArg{}
err := arg_parser.ExtractArgs(scope, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
if err != nil {
scope.Log("if: %s", err.Error())
close(output_chan)
Expand Down
2 changes: 1 addition & 1 deletion plugins/range.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (self RangePlugin) Call(
defer close(output_chan)

arg := &RangePluginArgs{}
err := arg_parser.ExtractArgs(scope, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
if err != nil {
scope.Log("range: %v", err)
return
Expand Down
4 changes: 2 additions & 2 deletions scope/scope_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type DestructorFunction struct {
func (self DestructorFunction) Call(
ctx context.Context, scope types.Scope, args *ordereddict.Dict) types.Any {
arg := DestructorFunctionArgs{}
err := arg_parser.ExtractArgs(scope, args, &arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, &arg)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -83,7 +83,7 @@ func (self *DestructorPlugin) Call(
defer close(output_chan)

arg := DestructorPluginArgs{}
err := arg_parser.ExtractArgs(scope, args, &arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, &arg)
if err != nil {
panic(err)
}
Expand Down
2 changes: 1 addition & 1 deletion scope/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (self _GetVersion) Info(scope types.Scope, type_map *types.TypeMap) *types.
func (self _GetVersion) Call(ctx context.Context,
scope_int types.Scope, args *ordereddict.Dict) types.Any {
arg := &_GetVersion{}
err := arg_parser.ExtractArgs(scope_int, args, arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope_int, args, arg)
if err != nil {
scope_int.Log("version: %s", err.Error())
return types.Null{}
Expand Down
7 changes: 4 additions & 3 deletions vfilter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/sebdah/goldie/v2"
"github.com/stretchr/testify/assert"
"www.velocidex.com/golang/vfilter/arg_parser"
"www.velocidex.com/golang/vfilter/plugins"
"www.velocidex.com/golang/vfilter/protocols"
"www.velocidex.com/golang/vfilter/types"
Expand Down Expand Up @@ -351,7 +352,7 @@ type PanicFunctionArgs struct {
func (self PanicFunction) Call(ctx context.Context, scope types.Scope, args *ordereddict.Dict) Any {
arg := PanicFunctionArgs{}

err := ExtractArgs(scope, args, &arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, &arg)
if err != nil {
scope.Log("Panic: %v", err)
return types.Null{}
Expand Down Expand Up @@ -380,7 +381,7 @@ type SetEnvFunction struct{}

func (self SetEnvFunction) Call(ctx context.Context, scope types.Scope, args *ordereddict.Dict) Any {
arg := SetEnvFunctionArgs{}
err := ExtractArgs(scope, args, &arg)
err := arg_parser.ExtractArgsWithContext(ctx, scope, args, &arg)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -1364,7 +1365,7 @@ func makeTestScope() types.Scope {
PluginName: "range",
Function: func(ctx context.Context, scope types.Scope, args *ordereddict.Dict) []Row {
arg := &_RangeArgs{}
ExtractArgs(scope, args, arg)
arg_parser.ExtractArgsWithContext(ctx, scope, args, arg)
var result []Row
for i := arg.Start; i <= arg.End; i++ {
result = append(result, ordereddict.NewDict().Set("value", i))
Expand Down
4 changes: 4 additions & 0 deletions visitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"

"www.velocidex.com/golang/vfilter/arg_parser"
"www.velocidex.com/golang/vfilter/materializer"
"www.velocidex.com/golang/vfilter/types"
)

Expand Down Expand Up @@ -256,6 +257,9 @@ func (self *Visitor) Visit(node interface{}) {
case *arg_parser.LazyExpressionWrapper:
self.Visit(t.Delegate())

case *materializer.InMemoryMatrializer:
return

default:
self.scope.Log("FormatToString: Unable to visit %T", node)
}
Expand Down