X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/e59b78c774872e33b9c69acc196989a0f565bdf4..bcad695db9a1c3aac5807faa153086e653107f51:/sdk/go/arvados/resource_list.go diff --git a/sdk/go/arvados/resource_list.go b/sdk/go/arvados/resource_list.go index 14ce098cfc..7f319b4121 100644 --- a/sdk/go/arvados/resource_list.go +++ b/sdk/go/arvados/resource_list.go @@ -4,7 +4,10 @@ package arvados -import "encoding/json" +import ( + "encoding/json" + "fmt" +) // ResourceListParams expresses which results are requested in a // list/index API. @@ -27,7 +30,44 @@ type Filter struct { Operand interface{} } -// MarshalJSON encodes a Filter in the form expected by the API. +// MarshalJSON encodes a Filter to a JSON array. func (f *Filter) MarshalJSON() ([]byte, error) { return json.Marshal([]interface{}{f.Attr, f.Operator, f.Operand}) } + +// UnmarshalJSON decodes a JSON array to a Filter. +func (f *Filter) UnmarshalJSON(data []byte) error { + var decoded interface{} + err := json.Unmarshal(data, &decoded) + if err != nil { + return err + } + switch decoded := decoded.(type) { + case string: + // Accept "(foo < bar)" as a more obvious way to spell + // ["(foo < bar)","=",true] + *f = Filter{decoded, "=", true} + case []interface{}: + if len(decoded) != 3 { + return fmt.Errorf("invalid filter %q: must have 3 decoded", data) + } + attr, ok := decoded[0].(string) + if !ok { + return fmt.Errorf("invalid filter attr %q", decoded[0]) + } + op, ok := decoded[1].(string) + if !ok { + return fmt.Errorf("invalid filter operator %q", decoded[1]) + } + operand := decoded[2] + switch operand.(type) { + case string, float64, []interface{}, nil, bool: + default: + return fmt.Errorf("invalid filter operand %q", decoded[2]) + } + *f = Filter{attr, op, operand} + default: + return fmt.Errorf("invalid filter: json decoded as %T instead of array or string", decoded) + } + return nil +}