diff --git a/encoding/gjson/gjson_z_unit_feature_set_test.go b/encoding/gjson/gjson_z_unit_feature_set_test.go index 1685e816f..49474fed9 100644 --- a/encoding/gjson/gjson_z_unit_feature_set_test.go +++ b/encoding/gjson/gjson_z_unit_feature_set_test.go @@ -8,6 +8,8 @@ package gjson_test import ( "bytes" + "encoding/json" + "fmt" "testing" "github.com/gogf/gf/v2/container/garray" @@ -347,3 +349,31 @@ func Test_Set_WithEmptyStruct(t *testing.T) { t.Assert(j.MustToJsonString(), `{"aa":"123"}`) }) } + +// Issue3108String +type Issue3108String struct { + Name string +} + +func (i Issue3108String) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"[%s]"`, i.Name)), nil +} + +func Test_Issue3108(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + type Issue3108 struct { + MyName Issue3108String `json:"my_name"` + } + obj := &Issue3108{MyName: Issue3108String{Name: "test"}} + + b, err := json.Marshal(obj) + t.AssertNil(err) + t.Log(string(b)) + t.Assert(string(b), `{"my_name":"[test]"}`) + + j := gjson.New(obj) + jb, err := j.ToJson() + t.AssertNil(err) + t.Assert(string(jb), `{"my_name":"[test]"}`) + }) +} diff --git a/util/gconv/gconv_map.go b/util/gconv/gconv_map.go index f9a510eec..6a74664e1 100644 --- a/util/gconv/gconv_map.go +++ b/util/gconv/gconv_map.go @@ -7,6 +7,7 @@ package gconv import ( + . "encoding/json" "reflect" "strings" @@ -380,6 +381,12 @@ func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) in // as it might be changed from pointer to struct. rvInterface = rvField.Interface() ) + + if _, ok := rvField.Interface().(Marshaler); ok { + dataMap[mapKey] = rvField.Interface() + return dataMap + } + switch { case hasNoTag && rtField.Anonymous: // It means this attribute field has no tag. diff --git a/util/gconv/gconv_z_unit_map_test.go b/util/gconv/gconv_z_unit_map_test.go index 9dca4ce39..376a133e3 100644 --- a/util/gconv/gconv_z_unit_map_test.go +++ b/util/gconv/gconv_z_unit_map_test.go @@ -8,6 +8,7 @@ package gconv_test import ( "encoding/json" + "fmt" "testing" "gopkg.in/yaml.v3" @@ -620,3 +621,27 @@ func TestMapWithJsonOmitEmpty(t *testing.T) { t.Assert(gconv.Map(s), g.Map{"Value": 1}) }) } + +// Issue3108String +type Issue3108String struct { + Name string +} + +func (i Issue3108String) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"[%s]"`, i.Name)), nil +} + +func Test_Issue3108(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + type Issue3108 struct { + MyName Issue3108String `json:"my_name"` + } + obj := &Issue3108{MyName: Issue3108String{Name: "test"}} + + converted := gconv.MapDeep(obj) + jsonData, err := json.Marshal(converted) + + t.AssertNil(err) + t.Assert(string(jsonData), `{"my_name":"[test]"}`) + }) +}