From 129455dc28ae7cb56466318ec259422d14851207 Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Wed, 6 May 2020 10:35:54 +0100 Subject: [PATCH] fix: Argument processing on pointers (#474) Fix Argument interface processing on struct pointer types which was broken by #428 and not quite corrected by #446. --- go.sum | 1 + redis/scan.go | 10 ++++------ redis/scan_test.go | 32 ++++++++++++++++++++++++++------ 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/go.sum b/go.sum index 5b5dd182..331fa698 100644 --- a/go.sum +++ b/go.sum @@ -7,4 +7,5 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/redis/scan.go b/redis/scan.go index 10c1d266..289cfd91 100644 --- a/redis/scan.go +++ b/redis/scan.go @@ -646,16 +646,14 @@ func flattenStruct(args Args, v reflect.Value) Args { continue } } - if fv.Kind() == reflect.Ptr { + if arg, ok := fv.Interface().(Argument); ok { + args = append(args, fs.name, arg.RedisArg()) + } else if fv.Kind() == reflect.Ptr { if !fv.IsNil() { args = append(args, fs.name, fv.Elem().Interface()) } } else { - if arg, ok := fv.Interface().(Argument); ok { - args = append(args, fs.name, arg.RedisArg()) - } else { - args = append(args, fs.name, fv.Interface()) - } + args = append(args, fs.name, fv.Interface()) } } return args diff --git a/redis/scan_test.go b/redis/scan_test.go index 8d06b3c5..67b1aace 100644 --- a/redis/scan_test.go +++ b/redis/scan_test.go @@ -419,12 +419,14 @@ func ExampleScanSlice() { // [{Earthbound 1} {Beat 4} {Red 5}] } +var now = time.Now() + var argsTests = []struct { title string actual redis.Args expected redis.Args }{ - {"struct ptr", + {"struct-ptr", redis.Args{}.AddFlat(&struct { I int `redis:"i"` U uint `redis:"u"` @@ -444,15 +446,23 @@ var argsTests = []struct { redis.Args{}.AddFlat(struct{ I int }{123}), redis.Args{"I", 123}, }, - {"struct with RedisArg", + {"struct-with-RedisArg-direct", redis.Args{}.AddFlat(struct{ T CustomTime }{CustomTime{Time: time.Unix(1573231058, 0)}}), redis.Args{"T", int64(1573231058)}, }, + {"struct-with-RedisArg-direct-ptr", + redis.Args{}.AddFlat(struct{ T *CustomTime }{&CustomTime{Time: time.Unix(1573231058, 0)}}), + redis.Args{"T", int64(1573231058)}, + }, + {"struct-with-RedisArg-ptr", + redis.Args{}.AddFlat(struct{ T *CustomTimePtr }{&CustomTimePtr{Time: time.Unix(1573231058, 0)}}), + redis.Args{"T", int64(1573231058)}, + }, {"slice", redis.Args{}.Add(1).AddFlat([]string{"a", "b", "c"}).Add(2), redis.Args{1, "a", "b", "c", 2}, }, - {"struct omitempty", + {"struct-omitempty", redis.Args{}.AddFlat(&struct { Sdp *durationArg `redis:"Sdp,omitempty"` }{ @@ -464,12 +474,22 @@ var argsTests = []struct { func TestArgs(t *testing.T) { for _, tt := range argsTests { - if !reflect.DeepEqual(tt.actual, tt.expected) { - t.Fatalf("%s is %v, want %v", tt.title, tt.actual, tt.expected) - } + t.Run(tt.title, func(t *testing.T) { + if !reflect.DeepEqual(tt.actual, tt.expected) { + t.Fatalf("is %v, want %v", tt.actual, tt.expected) + } + }) } } +type CustomTimePtr struct { + time.Time +} + +func (t *CustomTimePtr) RedisArg() interface{} { + return t.Unix() +} + type CustomTime struct { time.Time }