Skip to content

Commit a580104

Browse files
committed
fix: UnmarshalJSON of dst not called when gjson.Scan gogf#3769
1 parent 6b3fb60 commit a580104

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

encoding/gjson/gjson_z_unit_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
package gjson_test
88

99
import (
10+
"encoding/json"
1011
"fmt"
12+
"log"
1113
"testing"
1214

1315
"github.com/gogf/gf/v2/container/gmap"
@@ -615,3 +617,30 @@ func Test_Issue2520(t *testing.T) {
615617
t.Assert(gjson.MustEncodeString(t2), gjson.New(t2).MustToJsonString())
616618
})
617619
}
620+
621+
type UserIssue3769 struct {
622+
Id string
623+
}
624+
625+
func (u *UserIssue3769) UnmarshalJSON(data []byte) error {
626+
var um map[string]string
627+
err := json.Unmarshal(data, &um)
628+
if err != nil {
629+
return err
630+
}
631+
632+
if v, ok := um["uid"]; ok {
633+
u.Id = v
634+
}
635+
return nil
636+
}
637+
638+
func TestIssue(t *testing.T) {
639+
gtest.C(t, func(t *gtest.T) {
640+
data := `{"uid": "123", "uname": "456"}`
641+
var u UserIssue3769
642+
t.AssertNil(gjson.New(data).Scan(&u))
643+
log.Println(u)
644+
t.Assert(u.Id, `123`)
645+
})
646+
}

util/gconv/gconv_scan.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package gconv
88

99
import (
10+
stdjson "encoding/json"
1011
"reflect"
1112

1213
"github.com/gogf/gf/v2/errors/gcode"
@@ -197,6 +198,20 @@ func doConvertWithJsonCheck(srcValue interface{}, dstPointer interface{}) (ok bo
197198
}
198199

199200
default:
201+
switch dst := dstPointer.(type) {
202+
case stdjson.Unmarshaler:
203+
bytes, err := json.Marshal(srcValue)
204+
if err != nil {
205+
return false, err
206+
}
207+
208+
err = dst.UnmarshalJSON(bytes)
209+
if err != nil {
210+
return false, err
211+
}
212+
return true, nil
213+
}
214+
200215
// The `params` might be struct that implements interface function Interface, eg: gvar.Var.
201216
if v, ok := srcValue.(localinterface.IInterface); ok {
202217
return doConvertWithJsonCheck(v.Interface(), dstPointer)

0 commit comments

Comments
 (0)