From a77a6bb3d4bf2c8b030937e36c3415bd3f27c7e5 Mon Sep 17 00:00:00 2001 From: lxc <987712030@qq.com> Date: Fri, 23 Feb 2024 14:51:20 +0800 Subject: [PATCH] add: hscan data struct --- example_test.go | 35 +++++++++++++++++++++++++++++------ internal/hscan/structmap.go | 2 ++ internal/proto/writer.go | 6 ++++++ 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/example_test.go b/example_test.go index 62aa8cb56..e3bbb280e 100644 --- a/example_test.go +++ b/example_test.go @@ -2,6 +2,7 @@ package redis_test import ( "context" + "encoding/json" "errors" "fmt" "sync" @@ -344,6 +345,24 @@ func ExampleClient_ScanType_hashType() { // Output: 33 keys ready for use } +type Income struct { + Min float64 `json:"min"` + Max float64 `json:"max"` +} + +func (p *Income) MarshalBinary() (data []byte, err error) { + return json.Marshal(*p) +} + +func (p *Income) UnmarshalBinary(data []byte) error { + val := Income{} + if err := json.Unmarshal(data, &val); err != nil { + return err + } + *p = val + return nil +} + // ExampleMapStringStringCmd_Scan shows how to scan the results of a map fetch // into a struct. func ExampleMapStringStringCmd_Scan() { @@ -351,7 +370,9 @@ func ExampleMapStringStringCmd_Scan() { err := rdb.HMSet(ctx, "map", "name", "hello", "count", 123, - "correct", true).Err() + "correct", true, + "income", &Income{Max: 10, Min: 1}, + ).Err() if err != nil { panic(err) } @@ -363,9 +384,10 @@ func ExampleMapStringStringCmd_Scan() { } type data struct { - Name string `redis:"name"` - Count int `redis:"count"` - Correct bool `redis:"correct"` + Name string `redis:"name"` + Count int `redis:"count"` + Correct bool `redis:"correct"` + Income *Income `redis:"income"` } // Scan the results into the struct. @@ -374,8 +396,9 @@ func ExampleMapStringStringCmd_Scan() { panic(err) } - fmt.Println(d) - // Output: {hello 123 true} + fmt.Printf("name: %s count: %d correct: %v income: {max: %.0f, mix: %.0f}", + d.Name, d.Count, d.Correct, d.Income.Max, d.Income.Min) + // Output: name: hello count: 123 correct: true income: {max: 10, mix: 1} } // ExampleSliceCmd_Scan shows how to scan the results of a multi key fetch diff --git a/internal/hscan/structmap.go b/internal/hscan/structmap.go index 1a560e4a3..dae3e97f0 100644 --- a/internal/hscan/structmap.go +++ b/internal/hscan/structmap.go @@ -107,6 +107,8 @@ func (s StructValue) Scan(key string, value string) error { switch scan := v.Interface().(type) { case Scanner: return scan.ScanRedis(value) + case encoding.BinaryUnmarshaler: + return scan.UnmarshalBinary(util.StringToBytes(value)) case encoding.TextUnmarshaler: return scan.UnmarshalText(util.StringToBytes(value)) } diff --git a/internal/proto/writer.go b/internal/proto/writer.go index 78595cc4f..174bc9696 100644 --- a/internal/proto/writer.go +++ b/internal/proto/writer.go @@ -138,6 +138,12 @@ func (w *Writer) WriteArg(v interface{}) error { return err } return w.bytes(b) + case encoding.TextMarshaler: + b, err := v.MarshalText() + if err != nil { + return err + } + return w.bytes(b) case net.IP: return w.bytes(v) default: