From 2701698e6e91e6130de5bf17ac93c6eec85eb652 Mon Sep 17 00:00:00 2001 From: 5aaee9 <7685264+5aaee9@users.noreply.github.com> Date: Wed, 7 Jun 2023 06:07:14 +0000 Subject: [PATCH] objects: add RemarshJSONReflect --- pkgs/objects/json.go | 44 ++++++++++++++++++++++++++++++++++++++- pkgs/objects/json_test.go | 19 +++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/pkgs/objects/json.go b/pkgs/objects/json.go index 012d0e4..b18eb5c 100644 --- a/pkgs/objects/json.go +++ b/pkgs/objects/json.go @@ -1,6 +1,10 @@ package objects -import "encoding/json" +import ( + "encoding/json" + "errors" + "reflect" +) func RemarshJSON[T any](input any) (*T, error) { bytes, err := json.Marshal(input) @@ -15,3 +19,41 @@ func RemarshJSON[T any](input any) (*T, error) { return r, nil } + +var ErrTypeError = errors.New("type error") + +func RemarshJSONReflect[T any](input any, kind reflect.Type) (*T, error) { + data, err := json.Marshal(input) + if err != nil { + return nil, err + } + + if kind.Kind() == reflect.Ptr { + typ := kind.Elem() + dst := reflect.New(typ).Elem() + err := json.Unmarshal(data, dst.Addr().Interface()) + if err != nil { + return nil, err + } + + res, ok := dst.Addr().Interface().(*T) + if !ok { + return nil, ErrTypeError + } + + return res, nil + } + + dst := reflect.New(kind).Elem() + err = json.Unmarshal(data, dst.Addr().Interface()) + if err != nil { + return nil, err + } + + res, ok := dst.Interface().(T) + if !ok { + return nil, ErrTypeError + } + + return &res, nil +} diff --git a/pkgs/objects/json_test.go b/pkgs/objects/json_test.go index ad74df8..f1538ba 100644 --- a/pkgs/objects/json_test.go +++ b/pkgs/objects/json_test.go @@ -1,6 +1,7 @@ package objects_test import ( + "reflect" "testing" "github.com/5aaee9/utils/pkgs/json" @@ -20,3 +21,21 @@ func TestRemarshJSON(t *testing.T) { assert.NoError(t, err) assert.Equal(t, out.Data, "data test #1") } + +func TestRemarshJSONReflect(t *testing.T) { + out, err := objects.RemarshJSONReflect[TestStruct](json.JSON{ + "test": "data test #1", + }, reflect.TypeOf(TestStruct{})) + + assert.NoError(t, err) + assert.Equal(t, out.Data, "data test #1") + + ptr := new(TestStruct) + + out, err = objects.RemarshJSONReflect[TestStruct](json.JSON{ + "test": "data test #1", + }, reflect.ValueOf(ptr).Type()) + assert.NoError(t, err) + assert.Equal(t, out.Data, "data test #1") + assert.Equal(t, ptr.Data, "") +}