From 658de0fb6911c6215dd3e4ffdf641800e43c3964 Mon Sep 17 00:00:00 2001 From: epicmr Date: Wed, 12 Apr 2023 11:07:41 +0800 Subject: [PATCH] support pointer to object slice --- builder.go | 3 ++- format_test.go | 15 ++++++++++++++- pointer.go | 14 ++++++++++++-- slice.go | 4 +++- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/builder.go b/builder.go index 757c1a9..c6acac5 100644 --- a/builder.go +++ b/builder.go @@ -13,7 +13,8 @@ func makeBuilder(t reflect.Type) (builder, error) { case reflect.Struct: return makeStructBuilder(t) case reflect.Ptr: - if t.Elem().Kind() != reflect.Struct { + if t.Elem().Kind() != reflect.Struct && + t.Elem().Kind() != reflect.Slice { return makePrimitiveBuilder(t) } return makePointerBuilder(t) diff --git a/format_test.go b/format_test.go index 59fcdbc..5af9a5a 100644 --- a/format_test.go +++ b/format_test.go @@ -367,6 +367,19 @@ func TestFormat(t *testing.T) { format: "foo", output: `[{"foo":1}]`, }, + { + src: &[]struct { + Foo int `json:"foo"` + Bar int `json:"bar"` + }{ + { + Foo: 1, + Bar: 2, + }, + }, + format: "foo", + output: `[{"foo":1}]`, + }, { src: struct { Foo []int `json:"foo"` @@ -400,7 +413,7 @@ func TestFormat(t *testing.T) { }, } for i, tt := range tests { - t.Run(fmt.Sprintf("test #%d", i), func(t *testing.T) { + t.Run(fmt.Sprintf("test #%d %s %s", i, tt.format, tt.output), func(t *testing.T) { f := NewFormatter() var fields []string if tt.format != "" { diff --git a/pointer.go b/pointer.go index 74965d4..7739e92 100644 --- a/pointer.go +++ b/pointer.go @@ -1,6 +1,7 @@ package dynjson import ( + "errors" "reflect" ) @@ -25,7 +26,7 @@ func (f *pointerFormatter) format(src reflect.Value) (reflect.Value, error) { type pointerBuilder struct { t reflect.Type - elem *structBuilder + elem builder } func (b *pointerBuilder) build(fields []string, prefix string) (formatter, error) { @@ -37,7 +38,16 @@ func (b *pointerBuilder) build(fields []string, prefix string) (formatter, error } func makePointerBuilder(t reflect.Type) (*pointerBuilder, error) { - eb, err := makeStructBuilder(t.Elem()) + var eb builder + var err error + if t.Elem().Kind() == reflect.Struct { + eb, err = makeStructBuilder(t.Elem()) + } else if t.Elem().Kind() == reflect.Slice { + eb, err = makeSliceBuilder(t.Elem()) + } else { + return nil, errors.New("unable to handle this type") + } + if err != nil { return nil, err } diff --git a/slice.go b/slice.go index da02410..b997019 100644 --- a/slice.go +++ b/slice.go @@ -20,7 +20,9 @@ func (f *sliceFormatter) format(src reflect.Value) (reflect.Value, error) { } dst.Index(i).Set(dv) } - return dst, nil + dstAddr := reflect.New(f.t).Elem() + dstAddr.Set(dst) + return dstAddr, nil } type sliceBuilder struct {