This commit is contained in:
Hunk Zhu
2023-10-31 20:02:20 +08:00
committed by GitHub
parent afeca8cf9d
commit 0b71bc43a8
2 changed files with 71 additions and 6 deletions

View File

@ -377,6 +377,20 @@ func bindVarToStructAttr(structReflectValue reflect.Value, attrName string, valu
if empty.IsNil(value) {
structFieldValue.Set(reflect.Zero(structFieldValue.Type()))
} else {
// Try to call custom converter.
// Issue: https://github.com/gogf/gf/issues/3099
var (
customConverterInput reflect.Value
ok bool
)
if customConverterInput, ok = value.(reflect.Value); !ok {
customConverterInput = reflect.ValueOf(value)
}
if ok, err = callCustomConverter(customConverterInput, structFieldValue); ok || err != nil {
return
}
// Special handling for certain types:
// - Overwrite the default type converting logic of stdlib for time.Time/*time.Time.
var structFieldTypeName = structFieldValue.Type().String()
@ -399,13 +413,7 @@ func bindVarToStructAttr(structReflectValue reflect.Value, attrName string, valu
return
}
// Try to call custom converter.
if ok, err := callCustomConverter(reflect.ValueOf(value), structFieldValue); ok {
return err
}
// Common interface check.
var ok bool
if err, ok = bindVarToReflectValueWithInterfaceCheck(structFieldValue, value); ok {
return err
}

View File

@ -272,3 +272,60 @@ func TestConverter_CustomBasicType_ToStruct(t *testing.T) {
t.Assert(b.S, a)
})
}
// fix: https://github.com/gogf/gf/issues/3099
func TestConverter_CustomTimeType_ToStruct(t *testing.T) {
type timestamppb struct {
S string
}
type CustomGTime struct {
T *gtime.Time
}
type CustomPbTime struct {
T *timestamppb
}
gtest.C(t, func(t *gtest.T) {
var (
a = CustomGTime{
T: gtime.NewFromStrFormat("2023-10-26", "Y-m-d"),
}
b *CustomPbTime
)
err := gconv.Scan(a, &b)
t.AssertNil(err)
t.AssertNE(b, nil)
t.Assert(b.T.S, "")
})
gtest.C(t, func(t *gtest.T) {
err := gconv.RegisterConverter(func(in gtime.Time) (*timestamppb, error) {
return &timestamppb{
S: in.Local().Format("Y-m-d"),
}, nil
})
t.AssertNil(err)
err = gconv.RegisterConverter(func(in timestamppb) (*gtime.Time, error) {
return gtime.NewFromStr(in.S), nil
})
t.AssertNil(err)
})
gtest.C(t, func(t *gtest.T) {
var (
a = CustomGTime{
T: gtime.NewFromStrFormat("2023-10-26", "Y-m-d"),
}
b *CustomPbTime
c *CustomGTime
)
err := gconv.Scan(a, &b)
t.AssertNil(err)
t.AssertNE(b, nil)
t.AssertNE(b.T, nil)
err = gconv.Scan(b, &c)
t.AssertNil(err)
t.AssertNE(c, nil)
t.AssertNE(c.T, nil)
t.AssertEQ(a.T.Timestamp(), c.T.Timestamp())
})
}