mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
@ -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
|
||||
}
|
||||
|
||||
@ -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 ×tamppb{
|
||||
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())
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user