Skip to content
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
22 changes: 22 additions & 0 deletions arg_parser/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,28 @@ func ExtractArgsWithContext(
return err
}

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

args = NormalizeArgs(args)

v := reflect.ValueOf(target)
if v.Type().Kind() == reflect.Ptr {
v = v.Elem()
}

parser, err := GetParser(v)
if err != nil {
scope.Explainer().ParseArgs(args, target, err)
return nil, err
}

kw, err := parser.ParseAsFreeForm(ctx, scope, args, v)
scope.Explainer().ParseArgs(args, target, err)
return kw, err
}

// Try to retrieve an arg name from the Dict of args. Coerce the arg
// into something resembling a list of strings.
func _ExtractStringArray(
Expand Down
43 changes: 43 additions & 0 deletions arg_parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,49 @@ func (self *Parser) Parse(
return nil
}

// Parses the args as free form args:
// * Extract known fields into the target struct.
// * Other fields will be returns as the kwargs dict.
func (self *Parser) ParseAsFreeForm(
ctx context.Context, scope types.Scope, args *ordereddict.Dict, target reflect.Value) (*ordereddict.Dict, error) {
parsed := make([]string, 0, args.Len())
kwargs := ordereddict.NewDict()

for _, parser := range self.Fields {
value, pres := args.Get(parser.Field)
if !pres {
if parser.Required {
return nil, fmt.Errorf("Field %s is required", parser.Field)
}
continue
}

// Keep track of the fields we parsed.
parsed = append(parsed, parser.Field)

// Convert the value using the parser
new_value, err := parser.Parser(ctx, scope, args, value)
if err != nil {
return nil, fmt.Errorf("Field %s %w", parser.Field, err)
}

// Now set the field on the struct.
field_value := target.Field(parser.FieldIdx)
field_value.Set(reflect.ValueOf(new_value))
}

// Remaining fields are collected into the kwargs
if len(parsed) != args.Len() {
for _, item := range args.Items() {
if !utils.InString(&parsed, item.Key) {
kwargs.Set(item.Key, item.Value)
}
}
}

return dict.RowToDict(ctx, scope, kwargs), nil
}

// The plugin may specify the arg as being a LazyExpr, in which case
// it is completely up to it to evaluate the expression (if at all).
// Note: Reducing the lazy expression may yield a StoredQuery - it is
Expand Down
Loading