mirror of
https://github.com/yusing/godoxy.git
synced 2025-06-01 09:32:35 +02:00
refactor and fixed map-to-map deserialization
This commit is contained in:
parent
c1705a0209
commit
d8cac223ed
1 changed files with 41 additions and 20 deletions
|
@ -97,6 +97,33 @@ func ValidateWithFieldTags(s any) E.Error {
|
||||||
return errs.Error()
|
return errs.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ValidateWithCustomValidator(v reflect.Value) E.Error {
|
||||||
|
isStruct := false
|
||||||
|
for {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Pointer, reflect.Interface:
|
||||||
|
if v.IsNil() {
|
||||||
|
return E.Errorf("validate: v is %w", ErrNilValue)
|
||||||
|
}
|
||||||
|
if validate, ok := v.Interface().(CustomValidator); ok {
|
||||||
|
return validate.Validate()
|
||||||
|
}
|
||||||
|
if isStruct {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
v = v.Elem()
|
||||||
|
case reflect.Struct:
|
||||||
|
if !v.CanAddr() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
v = v.Addr()
|
||||||
|
isStruct = true
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func dive(dst reflect.Value) (v reflect.Value, t reflect.Type, err E.Error) {
|
func dive(dst reflect.Value) (v reflect.Value, t reflect.Type, err E.Error) {
|
||||||
dstT := dst.Type()
|
dstT := dst.Type()
|
||||||
for {
|
for {
|
||||||
|
@ -220,34 +247,28 @@ func Deserialize(src SerializedObject, dst any) (err E.Error) {
|
||||||
}
|
}
|
||||||
if hasValidateTag {
|
if hasValidateTag {
|
||||||
errs.Add(ValidateWithFieldTags(dstV.Interface()))
|
errs.Add(ValidateWithFieldTags(dstV.Interface()))
|
||||||
} else {
|
}
|
||||||
if dstV.CanAddr() {
|
if err := ValidateWithCustomValidator(dstV); err != nil {
|
||||||
dstV = dstV.Addr()
|
errs.Add(err)
|
||||||
}
|
|
||||||
if validator, ok := dstV.Interface().(CustomValidator); ok {
|
|
||||||
errs.Add(validator.Validate())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return errs.Error()
|
return errs.Error()
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
if dstV.IsNil() {
|
for k, v := range src {
|
||||||
dstV.Set(reflect.MakeMap(dstT))
|
|
||||||
}
|
|
||||||
for k := range src {
|
|
||||||
mapVT := dstT.Elem()
|
mapVT := dstT.Elem()
|
||||||
tmp := New(mapVT).Elem()
|
tmp := New(mapVT).Elem()
|
||||||
err := Convert(reflect.ValueOf(src[k]), tmp)
|
err := Convert(reflect.ValueOf(v), tmp)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
dstV.SetMapIndex(reflect.ValueOf(k), tmp)
|
|
||||||
} else {
|
|
||||||
errs.Add(err.Subject(k))
|
errs.Add(err.Subject(k))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := ValidateWithCustomValidator(tmp.Addr()); err != nil {
|
||||||
|
errs.Add(err.Subject(k))
|
||||||
|
} else {
|
||||||
|
dstV.SetMapIndex(reflect.ValueOf(k), tmp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if dstV.CanAddr() {
|
if err := ValidateWithCustomValidator(dstV); err != nil {
|
||||||
dstV = dstV.Addr()
|
errs.Add(err)
|
||||||
}
|
|
||||||
if validator, ok := dstV.Interface().(CustomValidator); ok {
|
|
||||||
errs.Add(validator.Validate())
|
|
||||||
}
|
}
|
||||||
return errs.Error()
|
return errs.Error()
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Add table
Reference in a new issue