refactor: rename Deserialize* to UnmarshalValidate*

This commit is contained in:
yusing
2025-04-05 11:58:11 +08:00
parent 2c0d58f692
commit 253e06923d
16 changed files with 33 additions and 40 deletions

View File

@@ -167,8 +167,8 @@ func dive(dst reflect.Value) (v reflect.Value, t reflect.Type, err gperr.Error)
}
}
// Deserialize takes a SerializedObject and a target value, and assigns the values in the SerializedObject to the target value.
// Deserialize ignores case differences between the field names in the SerializedObject and the target.
// MapUnmarshalValidate takes a SerializedObject and a target value, and assigns the values in the SerializedObject to the target value.
// MapUnmarshalValidate ignores case differences between the field names in the SerializedObject and the target.
//
// The target value must be a struct or a map[string]any.
// If the target value is a struct , and implements the MapUnmarshaller interface,
@@ -180,7 +180,7 @@ func dive(dst reflect.Value) (v reflect.Value, t reflect.Type, err gperr.Error)
// If the target value is a map[string]any the SerializedObject will be deserialized into the map.
//
// The function returns an error if the target value is not a struct or a map[string]any, or if there is an error during deserialization.
func Deserialize(src SerializedObject, dst any) (err gperr.Error) {
func MapUnmarshalValidate(src SerializedObject, dst any) (err gperr.Error) {
dstV := reflect.ValueOf(dst)
dstT := dstV.Type()
@@ -341,9 +341,6 @@ func Convert(src reflect.Value, dst reflect.Value) gperr.Error {
case srcT.AssignableTo(dstT):
dst.Set(src)
return nil
// case srcT.ConvertibleTo(dstT):
// dst.Set(src.Convert(dstT))
// return nil
case srcKind == reflect.String:
if convertible, err := ConvertString(src.String(), dst); convertible {
return err
@@ -371,7 +368,7 @@ func Convert(src reflect.Value, dst reflect.Value) gperr.Error {
if !ok {
return ErrUnsupportedConversion.Subject(dstT.String() + " to " + srcT.String())
}
return Deserialize(obj, dst.Addr().Interface())
return MapUnmarshalValidate(obj, dst.Addr().Interface())
case srcKind == reflect.Slice:
if src.Len() == 0 {
return nil
@@ -448,7 +445,7 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr gpe
dst.Set(reflect.ValueOf(i).Convert(dstT))
return
}
// check if (*T).Convertor is implemented
// check if target implements string parser
if parser, ok := dst.Addr().Interface().(strutils.Parser); ok {
return true, gperr.Wrap(parser.Parse(src))
}
@@ -458,7 +455,7 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr gpe
case reflect.Slice:
src = strings.TrimSpace(src)
isMultiline := strings.ContainsRune(src, '\n')
// one liner is comma separated list
// treats one liner without leading dash as comma separated list
if !isMultiline && src[0] != '-' {
values := strutils.CommaSeperatedList(src)
dst.Set(reflect.MakeSlice(dst.Type(), len(values), len(values)))
@@ -493,21 +490,21 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr gpe
return true, Convert(reflect.ValueOf(tmp), dst)
}
func DeserializeYAML[T any](data []byte, target *T) gperr.Error {
func UnmarshalValidateYAML[T any](data []byte, target *T) gperr.Error {
m := make(map[string]any)
if err := yaml.Unmarshal(data, m); err != nil {
return gperr.Wrap(err)
}
return Deserialize(m, target)
return MapUnmarshalValidate(m, target)
}
func DeserializeYAMLMap[V any](data []byte) (_ functional.Map[string, V], err gperr.Error) {
func UnmarshalValidateYAMLMap[V any](data []byte) (_ functional.Map[string, V], err gperr.Error) {
m := make(map[string]any)
if err = gperr.Wrap(yaml.Unmarshal(data, m)); err != nil {
return
}
m2 := make(map[string]V, len(m))
if err = Deserialize(m, m2); err != nil {
if err = MapUnmarshalValidate(m, m2); err != nil {
return
}
return functional.NewMapFrom(m2), nil

View File

@@ -40,7 +40,7 @@ func TestDeserialize(t *testing.T) {
t.Run("deserialize", func(t *testing.T) {
var s2 S
err := Deserialize(testStructSerialized, &s2)
err := MapUnmarshalValidate(testStructSerialized, &s2)
ExpectNoError(t, err)
ExpectEqual(t, s2, testStruct)
})
@@ -60,13 +60,13 @@ func TestDeserializeAnonymousField(t *testing.T) {
}
// all, anon := extractFields(reflect.TypeOf(s2))
// t.Fatalf("anon %v, all %v", anon, all)
err := Deserialize(map[string]any{"a": 1, "b": 2, "c": 3}, &s)
err := MapUnmarshalValidate(map[string]any{"a": 1, "b": 2, "c": 3}, &s)
ExpectNoError(t, err)
ExpectEqual(t, s.A, 1)
ExpectEqual(t, s.B, 2)
ExpectEqual(t, s.C, 3)
err = Deserialize(map[string]any{"a": 1, "b": 2, "c": 3}, &s2)
err = MapUnmarshalValidate(map[string]any{"a": 1, "b": 2, "c": 3}, &s2)
ExpectNoError(t, err)
ExpectEqual(t, s2.A, 1)
ExpectEqual(t, s2.B, 2)
@@ -148,7 +148,7 @@ func (c *testType) Parse(v string) (err error) {
func TestConvertor(t *testing.T) {
t.Run("valid", func(t *testing.T) {
m := new(testModel)
ExpectNoError(t, Deserialize(map[string]any{"Test": "123"}, m))
ExpectNoError(t, MapUnmarshalValidate(map[string]any{"Test": "123"}, m))
ExpectEqual(t, m.Test.foo, 123)
ExpectEqual(t, m.Test.bar, "123")
@@ -156,18 +156,18 @@ func TestConvertor(t *testing.T) {
t.Run("int_to_string", func(t *testing.T) {
m := new(testModel)
ExpectNoError(t, Deserialize(map[string]any{"Test": "123"}, m))
ExpectNoError(t, MapUnmarshalValidate(map[string]any{"Test": "123"}, m))
ExpectEqual(t, m.Test.foo, 123)
ExpectEqual(t, m.Test.bar, "123")
ExpectNoError(t, Deserialize(map[string]any{"Baz": 123}, m))
ExpectNoError(t, MapUnmarshalValidate(map[string]any{"Baz": 123}, m))
ExpectEqual(t, m.Baz, "123")
})
t.Run("invalid", func(t *testing.T) {
m := new(testModel)
ExpectError(t, ErrUnsupportedConversion, Deserialize(map[string]any{"Test": struct{}{}}, m))
ExpectError(t, ErrUnsupportedConversion, MapUnmarshalValidate(map[string]any{"Test": struct{}{}}, m))
})
}

View File

@@ -13,10 +13,6 @@ type CustomValidator interface {
Validate() gperr.Error
}
func Validator() *validator.Validate {
return validate
}
func MustRegisterValidation(tag string, fn validator.Func) {
err := validate.RegisterValidation(tag, fn)
if err != nil {