feat(scan): scan time.Time sets the default decoding (#2413)

* feat(scan): scan time.Time uses `UnmarshalText(RFC3339)` interface decoding by default
This commit is contained in:
Monkey 2023-02-07 20:23:39 +08:00 committed by GitHub
parent 9d5e48507e
commit 8db6eeed27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 1 deletions

View File

@ -1900,6 +1900,25 @@ var _ = Describe("Commands", func() {
Key2: 123, Key2: 123,
Time: TimeValue{Time: time.Time{}}, Time: TimeValue{Time: time.Time{}},
})) }))
type data2 struct {
Key1 string `redis:"key1"`
Key2 int `redis:"key2"`
Time time.Time `redis:"time"`
}
err = client.HSet(ctx, "hash", &data2{
Key1: "hello2",
Key2: 200,
Time: now,
}).Err()
Expect(err).NotTo(HaveOccurred())
var d2 data2
err = client.HMGet(ctx, "hash", "key1", "key2", "time").Scan(&d2)
Expect(err).NotTo(HaveOccurred())
Expect(d2.Key1).To(Equal("hello2"))
Expect(d2.Key2).To(Equal(200))
Expect(d2.Time.Unix()).To(Equal(now.Unix()))
}) })
It("should HIncrBy", func() { It("should HIncrBy", func() {

View File

@ -200,4 +200,16 @@ var _ = Describe("Scan", func() {
Expect(td.Time.UnixNano()).To(Equal(now.UnixNano())) Expect(td.Time.UnixNano()).To(Equal(now.UnixNano()))
Expect(td.Time.Format(time.RFC3339Nano)).To(Equal(now.Format(time.RFC3339Nano))) Expect(td.Time.Format(time.RFC3339Nano)).To(Equal(now.Format(time.RFC3339Nano)))
}) })
It("should time.Time RFC3339Nano", func() {
type TimeTime struct {
Time time.Time `redis:"time"`
}
now := time.Now()
var tt TimeTime
Expect(Scan(&tt, i{"time"}, i{now.Format(time.RFC3339Nano)})).NotTo(HaveOccurred())
Expect(now.Unix()).To(Equal(tt.Time.Unix()))
})
}) })

View File

@ -1,10 +1,13 @@
package hscan package hscan
import ( import (
"encoding"
"fmt" "fmt"
"reflect" "reflect"
"strings" "strings"
"sync" "sync"
"github.com/redis/go-redis/v9/internal/util"
) )
// structMap contains the map of struct fields for target structs // structMap contains the map of struct fields for target structs
@ -97,8 +100,11 @@ func (s StructValue) Scan(key string, value string) error {
} }
if isPtr && v.Type().NumMethod() > 0 && v.CanInterface() { if isPtr && v.Type().NumMethod() > 0 && v.CanInterface() {
if scan, ok := v.Interface().(Scanner); ok { switch scan := v.Interface().(type) {
case Scanner:
return scan.ScanRedis(value) return scan.ScanRedis(value)
case encoding.TextUnmarshaler:
return scan.UnmarshalText(util.StringToBytes(value))
} }
} }