Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add: hscan data struct #2926

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
35 changes: 29 additions & 6 deletions example_test.go
Expand Up @@ -2,6 +2,7 @@ package redis_test

import (
"context"
"encoding/json"
"errors"
"fmt"
"sync"
Expand Down Expand Up @@ -344,14 +345,34 @@ 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() {
rdb.FlushDB(ctx)
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)
}
Expand All @@ -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.
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions internal/hscan/structmap.go
Expand Up @@ -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))
}
Expand Down
6 changes: 6 additions & 0 deletions internal/proto/writer.go
Expand Up @@ -138,7 +138,13 @@
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:

Check failure on line 147 in internal/proto/writer.go

View workflow job for this annotation

GitHub Actions / lint

SA4020: unreachable case clause: encoding.TextMarshaler will always match before net.IP (staticcheck)
return w.bytes(v)
default:
return fmt.Errorf(
Expand Down