From 0636b4f659f9c12a802c6d401b684b564f1a490a Mon Sep 17 00:00:00 2001 From: Sydonian <794346190@qq.com> Date: Thu, 25 May 2023 11:18:42 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E8=B0=83=E8=AF=95=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/serder/serder.go | 19 +++++++++++++++++++ utils/serder/serder_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/utils/serder/serder.go b/utils/serder/serder.go index 2c1c970..80f984b 100644 --- a/utils/serder/serder.go +++ b/utils/serder/serder.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "reflect" + "time" mp "github.com/mitchellh/mapstructure" ) @@ -26,12 +27,30 @@ type TypedSerderOption struct { TypeFieldName string } +func parseTimeHook(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { + if t != reflect.TypeOf(time.Time{}) { + return data, nil + } + + switch f.Kind() { + case reflect.String: + return time.Parse(time.RFC3339, data.(string)) + case reflect.Float64: + return time.Unix(0, int64(data.(float64))*int64(time.Millisecond)), nil + case reflect.Int64: + return time.Unix(0, data.(int64)*int64(time.Millisecond)), nil + default: + return data, nil + } +} + func MapToObject(m map[string]any, obj any) error { config := &mp.DecoderConfig{ TagName: "json", Squash: true, WeaklyTypedInput: true, Result: obj, + DecodeHook: mp.ComposeDecodeHookFunc(parseTimeHook), } decoder, err := mp.NewDecoder(config) diff --git a/utils/serder/serder_test.go b/utils/serder/serder_test.go index f0d4fd1..4355a5e 100644 --- a/utils/serder/serder_test.go +++ b/utils/serder/serder_test.go @@ -2,6 +2,7 @@ package serder import ( "testing" + "time" . "github.com/smartystreets/goconvey/convey" myreflect "gitlink.org.cn/cloudream/common/utils/reflect" @@ -31,6 +32,31 @@ func Test_MapToObject(t *testing.T) { So(st.C, ShouldEqual, 1234) }) + Convey("包含Time,先从结构体转为JSON,再从JSON转为Map,最后变回结构体", t, func() { + type Struct struct { + Time time.Time + NilTime *time.Time + } + + var st = Struct{ + Time: time.Now(), + NilTime: nil, + } + + data, err := ObjectToJSON(st) + So(err, ShouldBeNil) + + var mp map[string]any + err = JSONToObject(data, &mp) + So(err, ShouldBeNil) + + var st2 Struct + err = MapToObject(mp, &st2) + So(err, ShouldBeNil) + + So(st.Time, ShouldEqual, st2.Time) + So(st.NilTime, ShouldEqual, st2.NilTime) + }) } func Test_TypedMapToObject(t *testing.T) {