Repository: goccy/go-json
Pull request #498 (2024-02-18 12:43:08)

Use io package instead of ioutil package


Patch:
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index 34b30ed..cb5a700 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -85,7 +85,8 @@ jobs:
           go-version: '1.21'
       - name: measure coverage
         run: make cover
-      - uses: codecov/codecov-action@v3
+      - uses: codecov/codecov-action@v4
         with:
           fail_ci_if_error: true
           verbose: true
+          token: ${{ secrets.CODECOV_TOKEN }}
diff --git a/benchmarks/go.mod b/benchmarks/go.mod
index 73ca9db..6fd858e 100644
--- a/benchmarks/go.mod
+++ b/benchmarks/go.mod
@@ -1,6 +1,6 @@
 module benchmark
 
-go 1.12
+go 1.19
 
 require (
 	github.com/francoispqt/gojay v1.2.13
@@ -9,9 +9,14 @@ require (
 	github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe
 	github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7
 	github.com/segmentio/encoding v0.2.4
-	github.com/stretchr/testify v1.7.0 // indirect
 	github.com/valyala/fastjson v1.6.3
 	github.com/wI2L/jettison v0.7.1
 )
 
+require (
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.1 // indirect
+	github.com/stretchr/testify v1.7.0 // indirect
+)
+
 replace github.com/goccy/go-json => ../
diff --git a/benchmarks/go.sum b/benchmarks/go.sum
index fd8aa9b..9c5f8ff 100644
--- a/benchmarks/go.sum
+++ b/benchmarks/go.sum
@@ -56,7 +56,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
 github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe h1:W/GaMY0y69G4cFlmsC6B9sbuo2fP8OFP1ABjt4kPz+w=
@@ -71,7 +70,6 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
 github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -182,7 +180,6 @@ google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9M
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/internal/encoder/compact.go b/internal/encoder/compact.go
index 0eb9545..e287a6c 100644
--- a/internal/encoder/compact.go
+++ b/internal/encoder/compact.go
@@ -213,8 +213,8 @@ func compactString(dst, src []byte, cursor int64, escape bool) ([]byte, int64, e
 				dst = append(dst, src[start:cursor]...)
 				dst = append(dst, `\u202`...)
 				dst = append(dst, hex[src[cursor+2]&0xF])
-				cursor += 2
 				start = cursor + 3
+				cursor += 2
 			}
 		}
 		switch c {
diff --git a/internal/encoder/compiler.go b/internal/encoder/compiler.go
index 3ae39ba..37b7aa3 100644
--- a/internal/encoder/compiler.go
+++ b/internal/encoder/compiler.go
@@ -480,7 +480,7 @@ func (c *Compiler) mapCode(typ *runtime.Type) (*MapCode, error) {
 
 func (c *Compiler) listElemCode(typ *runtime.Type) (Code, error) {
 	switch {
-	case c.isPtrMarshalJSONType(typ):
+	case c.implementsMarshalJSONType(typ) || c.implementsMarshalJSONType(runtime.PtrTo(typ)):
 		return c.marshalJSONCode(typ)
 	case !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType):
 		return c.marshalTextCode(typ)


Test patch:
diff --git a/benchmarks/bench_test.go b/benchmarks/bench_test.go
index d671811..d45331b 100644
--- a/benchmarks/bench_test.go
+++ b/benchmarks/bench_test.go
@@ -15,7 +15,6 @@ import (
 	"compress/gzip"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"strings"
 	"testing"
@@ -56,7 +55,7 @@ func codeInit() {
 	if err != nil {
 		panic(err)
 	}
-	data, err := ioutil.ReadAll(gz)
+	data, err := io.ReadAll(gz)
 	if err != nil {
 		panic(err)
 	}
@@ -104,7 +103,7 @@ func Benchmark_EncodeBigData_GoJson(b *testing.B) {
 		b.StartTimer()
 	}
 	b.RunParallel(func(pb *testing.PB) {
-		enc := json.NewEncoder(ioutil.Discard)
+		enc := json.NewEncoder(io.Discard)
 		for pb.Next() {
 			if err := enc.Encode(&codeStruct); err != nil {
 				b.Fatal("Encode:", err)
@@ -122,7 +121,7 @@ func Benchmark_EncodeBigData_EncodingJson(b *testing.B) {
 		b.StartTimer()
 	}
 	b.RunParallel(func(pb *testing.PB) {
-		enc := stdjson.NewEncoder(ioutil.Discard)
+		enc := stdjson.NewEncoder(io.Discard)
 		for pb.Next() {
 			if err := enc.Encode(&codeStruct); err != nil {
 				b.Fatal("Encode:", err)
@@ -141,7 +140,7 @@ func Benchmark_EncodeBigData_JsonIter(b *testing.B) {
 	}
 	var json = jsoniter.ConfigCompatibleWithStandardLibrary
 	b.RunParallel(func(pb *testing.PB) {
-		enc := json.NewEncoder(ioutil.Discard)
+		enc := json.NewEncoder(io.Discard)
 		for pb.Next() {
 			if err := enc.Encode(&codeStruct); err != nil {
 				b.Fatal("Encode:", err)
@@ -159,7 +158,7 @@ func Benchmark_EncodeBigData_SegmentioJson(b *testing.B) {
 		b.StartTimer()
 	}
 	b.RunParallel(func(pb *testing.PB) {
-		enc := segmentiojson.NewEncoder(ioutil.Discard)
+		enc := segmentiojson.NewEncoder(io.Discard)
 		for pb.Next() {
 			if err := enc.Encode(&codeStruct); err != nil {
 				b.Fatal("Encode:", err)
@@ -316,7 +315,7 @@ func Benchmark_EncodeRawMessage_EncodingJson(b *testing.B) {
 	}{}
 
 	b.RunParallel(func(pb *testing.PB) {
-		enc := stdjson.NewEncoder(ioutil.Discard)
+		enc := stdjson.NewEncoder(io.Discard)
 		for pb.Next() {
 			if err := enc.Encode(&m); err != nil {
 				b.Fatal("Encode:", err)
@@ -336,7 +335,7 @@ func Benchmark_EncodeRawMessage_JsonIter(b *testing.B) {
 	var json = jsoniter.ConfigCompatibleWithStandardLibrary
 
 	b.RunParallel(func(pb *testing.PB) {
-		enc := json.NewEncoder(ioutil.Discard)
+		enc := json.NewEncoder(io.Discard)
 		for pb.Next() {
 			if err := enc.Encode(&m); err != nil {
 				b.Fatal("Encode:", err)
@@ -353,7 +352,7 @@ func Benchmark_EncodeRawMessage_GoJson(b *testing.B) {
 		B json.RawMessage
 	}{}
 	b.RunParallel(func(pb *testing.PB) {
-		enc := json.NewEncoder(ioutil.Discard)
+		enc := json.NewEncoder(io.Discard)
 		for pb.Next() {
 			if err := enc.Encode(&m); err != nil {
 				b.Fatal("Encode:", err)
diff --git a/stream_test.go b/stream_test.go
index edb680c..7b32df8 100644
--- a/stream_test.go
+++ b/stream_test.go
@@ -9,7 +9,6 @@ import (
 	"compress/gzip"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"log"
 	"net"
 	"net/http"
@@ -234,7 +233,7 @@ func TestDecoderBuffered(t *testing.T) {
 	if m.Name != "Gopher" {
 		t.Errorf("Name = %q; want Gopher", m.Name)
 	}
-	rest, err := ioutil.ReadAll(d.Buffered())
+	rest, err := io.ReadAll(d.Buffered())
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/test/cover/cover_slice_test.go b/test/cover/cover_slice_test.go
index 61de9a5..70a0306 100644
--- a/test/cover/cover_slice_test.go
+++ b/test/cover/cover_slice_test.go
@@ -16,6 +16,18 @@ func (coverSliceMarshalJSON) MarshalJSON() ([]byte, error) {
 	return []byte(`"hello"`), nil
 }
 
+type coverSliceMarshalJSONMap map[string]any
+
+func (c coverSliceMarshalJSONMap) MarshalJSON() ([]byte, error) {
+	return json.Marshal(map[string]any(c))
+}
+
+type coverSliceMarshalJSONMapPtr map[string]any
+
+func (c *coverSliceMarshalJSONMapPtr) MarshalJSON() ([]byte, error) {
+	return json.Marshal(map[string]any(*c))
+}
+
 type coverSliceMarshalText struct {
 	A int
 }
@@ -152,6 +164,22 @@ func TestCoverSlice(t *testing.T) {
 			name: "SliceMarshalJSON",
 			data: []coverSliceMarshalJSON{{A: 1}, {A: 2}},
 		},
+		{
+			name: "SliceMarshalJSONMap",
+			data: []coverSliceMarshalJSONMap{{"foo": "bar"}, {"some": 1}},
+		},
+		{
+			name: "SliceMarshalJSONMap",
+			data: []*coverSliceMarshalJSONMap{{"foo": "bar"}, {"some": 1}},
+		},
+		{
+			name: "SliceMarshalJSONMap",
+			data: []coverSliceMarshalJSONMapPtr{{"foo": "bar"}, {"some": 1}},
+		},
+		{
+			name: "SliceMarshalJSONMap",
+			data: []*coverSliceMarshalJSONMapPtr{{"foo": "bar"}, {"some": 1}},
+		},
 		{
 			name: "SliceMarshalText",
 			data: []coverSliceMarshalText{{A: 1}, {A: 2}},