mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
improve package gconv
This commit is contained in:
@ -112,11 +112,11 @@ func (r *Request) doParse(pointer interface{}, requestType int) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := j.GetStructs(".", pointer); err != nil {
|
||||
if err = j.GetStructs(".", pointer); err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < reflectVal2.Len(); i++ {
|
||||
if err := gvalid.CheckStruct(reflectVal2.Index(i), nil); err != nil {
|
||||
if err = gvalid.CheckStruct(reflectVal2.Index(i), nil); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@ -443,3 +443,12 @@ func (t *Time) UnmarshalJSON(b []byte) error {
|
||||
t.Time = newTime.Time
|
||||
return nil
|
||||
}
|
||||
|
||||
//// UnmarshalValue is an interface implement which sets any type of value for Time.
|
||||
//func (t *Time) UnmarshalValue(value interface{}) error {
|
||||
// vTime := New(value)
|
||||
// if vTime != nil {
|
||||
// *t = *vTime
|
||||
// }
|
||||
// return gerror.Newf(`invalid time value: %v`, value)
|
||||
//}
|
||||
|
||||
@ -119,11 +119,9 @@ func doStruct(params interface{}, pointer interface{}, mapping ...map[string]str
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalValue.
|
||||
// Assign value with interface UnmarshalValue.
|
||||
// Note that only pointer can implement interface UnmarshalValue.
|
||||
if v, ok := pointerReflectValue.Interface().(apiUnmarshalValue); ok {
|
||||
return v.UnmarshalValue(params)
|
||||
// Normal unmarshalling interfaces checks.
|
||||
if err, ok := bindVarToReflectValueWithInterfaceCheck(pointerReflectValue, params); ok {
|
||||
return err
|
||||
}
|
||||
|
||||
// It automatically creates struct object if necessary.
|
||||
@ -133,8 +131,13 @@ func doStruct(params interface{}, pointer interface{}, mapping ...map[string]str
|
||||
e := reflect.New(pointerElemReflectValue.Type().Elem()).Elem()
|
||||
pointerElemReflectValue.Set(e.Addr())
|
||||
}
|
||||
if v, ok := pointerElemReflectValue.Interface().(apiUnmarshalValue); ok {
|
||||
return v.UnmarshalValue(params)
|
||||
fmt.Println(pointerElemReflectValue.Type())
|
||||
//if v, ok := pointerElemReflectValue.Interface().(apiUnmarshalValue); ok {
|
||||
// return v.UnmarshalValue(params)
|
||||
//}
|
||||
// Note that it's `pointerElemReflectValue` here not `pointerReflectValue`.
|
||||
if err, ok := bindVarToReflectValueWithInterfaceCheck(pointerElemReflectValue, params); ok {
|
||||
return err
|
||||
}
|
||||
// Retrieve its element, may be struct at last.
|
||||
pointerElemReflectValue = pointerElemReflectValue.Elem()
|
||||
@ -286,25 +289,29 @@ func bindVarToStructAttr(elem reflect.Value, name string, value interface{}, map
|
||||
}
|
||||
|
||||
// bindVarToReflectValueWithInterfaceCheck does binding using common interfaces checks.
|
||||
func bindVarToReflectValueWithInterfaceCheck(structFieldValue reflect.Value, value interface{}) (err error, ok bool) {
|
||||
if structFieldValue.CanAddr() {
|
||||
pointer := structFieldValue.Addr().Interface()
|
||||
if v, ok := pointer.(apiUnmarshalValue); ok {
|
||||
return v.UnmarshalValue(value), ok
|
||||
func bindVarToReflectValueWithInterfaceCheck(reflectValue reflect.Value, value interface{}) (err error, ok bool) {
|
||||
var pointer interface{}
|
||||
if reflectValue.Kind() != reflect.Ptr && reflectValue.CanAddr() {
|
||||
// Not a pointer, but can token address, that makes it can be unmarshalled.
|
||||
pointer = reflectValue.Addr().Interface()
|
||||
} else {
|
||||
pointer = reflectValue.Interface()
|
||||
}
|
||||
if v, ok := pointer.(apiUnmarshalValue); ok {
|
||||
return v.UnmarshalValue(value), ok
|
||||
}
|
||||
if v, ok := pointer.(apiUnmarshalText); ok {
|
||||
if s, ok := value.(string); ok {
|
||||
return v.UnmarshalText([]byte(s)), ok
|
||||
}
|
||||
if v, ok := pointer.(apiUnmarshalText); ok {
|
||||
if s, ok := value.(string); ok {
|
||||
return v.UnmarshalText([]byte(s)), ok
|
||||
}
|
||||
if b, ok := value.([]byte); ok {
|
||||
return v.UnmarshalText(b), ok
|
||||
}
|
||||
}
|
||||
if v, ok := pointer.(apiSet); ok {
|
||||
v.Set(value)
|
||||
return nil, ok
|
||||
if b, ok := value.([]byte); ok {
|
||||
return v.UnmarshalText(b), ok
|
||||
}
|
||||
}
|
||||
if v, ok := pointer.(apiSet); ok {
|
||||
v.Set(value)
|
||||
return nil, ok
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
|
||||
@ -48,6 +48,11 @@ func Test_Struct_UnmarshalValue1(t *testing.T) {
|
||||
err := gconv.Struct(g.Map{"ServiceDate": nil}, st)
|
||||
t.AssertNE(err, nil)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
st := &MyTimeSt{}
|
||||
err := gconv.Struct(g.Map{"ServiceDate": "error"}, st)
|
||||
t.AssertNE(err, nil)
|
||||
})
|
||||
}
|
||||
|
||||
type Pkg struct {
|
||||
|
||||
Reference in New Issue
Block a user