You've already forked json-iterator
							
							
				mirror of
				https://github.com/json-iterator/go.git
				synced 2025-10-31 00:07:40 +02:00 
			
		
		
		
	suport encode map[interface{}]interface{}
This commit is contained in:
		| @@ -2,12 +2,12 @@ package jsoniter | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"github.com/modern-go/concurrent" | ||||
| 	"github.com/modern-go/reflect2" | ||||
| 	"io" | ||||
| 	"reflect" | ||||
| 	"sync" | ||||
| 	"unsafe" | ||||
| 	"github.com/modern-go/concurrent" | ||||
| 	"reflect" | ||||
| ) | ||||
|  | ||||
| // Config customize how the API should behave. | ||||
| @@ -63,7 +63,6 @@ var ConfigFastest = Config{ | ||||
| 	ObjectFieldMustBeSimpleString: true, // do not unescape object field | ||||
| }.Froze() | ||||
|  | ||||
|  | ||||
| type frozenConfig struct { | ||||
| 	configBeforeFrozen            Config | ||||
| 	sortMapKeys                   bool | ||||
|   | ||||
| @@ -2,8 +2,8 @@ package test | ||||
|  | ||||
| import ( | ||||
| 	"github.com/json-iterator/go" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 	"github.com/modern-go/reflect2" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 	"reflect" | ||||
| 	"strconv" | ||||
| 	"testing" | ||||
|   | ||||
| @@ -2,9 +2,9 @@ package extra | ||||
|  | ||||
| import ( | ||||
| 	"github.com/json-iterator/go" | ||||
| 	"unsafe" | ||||
| 	"unicode/utf8" | ||||
| 	"github.com/modern-go/reflect2" | ||||
| 	"unicode/utf8" | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| // safeSet holds the value true if the ASCII character with the given array | ||||
| @@ -171,18 +171,18 @@ func (codec *binaryAsStringCodec) Encode(ptr unsafe.Pointer, stream *jsoniter.St | ||||
| func readHex(iter *jsoniter.Iterator, b1, b2 byte) byte { | ||||
| 	var ret byte | ||||
| 	if b1 >= '0' && b1 <= '9' { | ||||
| 		ret = b1-'0' | ||||
| 		ret = b1 - '0' | ||||
| 	} else if b1 >= 'a' && b1 <= 'f' { | ||||
| 		ret = b1-'a'+10 | ||||
| 		ret = b1 - 'a' + 10 | ||||
| 	} else { | ||||
| 		iter.ReportError("read hex", "expects 0~9 or a~f, but found "+string([]byte{b1})) | ||||
| 		return 0 | ||||
| 	} | ||||
| 	ret = ret * 16 | ||||
| 	if b2 >= '0' && b2 <= '9' { | ||||
| 		ret = b2-'0' | ||||
| 		ret = b2 - '0' | ||||
| 	} else if b2 >= 'a' && b2 <= 'f' { | ||||
| 		ret = b2-'a'+10 | ||||
| 		ret = b2 - 'a' + 10 | ||||
| 	} else { | ||||
| 		iter.ReportError("read hex", "expects 0~9 or a~f, but found "+string([]byte{b2})) | ||||
| 		return 0 | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| package extra | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 	"github.com/json-iterator/go" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
|   | ||||
| @@ -31,3 +31,14 @@ func Test_read_map_with_reader(t *testing.T) { | ||||
| 	should.Equal(m2, m1) | ||||
| 	should.Equal("1.0.76", m1["note"].(map[string]interface{})["CoreServices"].(map[string]interface{})["version_name"]) | ||||
| } | ||||
|  | ||||
| func Test_map_eface_of_eface(t *testing.T) { | ||||
| 	should := require.New(t) | ||||
| 	json := jsoniter.ConfigCompatibleWithStandardLibrary | ||||
| 	output, err := json.MarshalToString(map[interface{}]interface{}{ | ||||
| 		"1": 2, | ||||
| 		3:   "4", | ||||
| 	}) | ||||
| 	should.NoError(err) | ||||
| 	should.Equal(`{"1":2,"3":"4"}`, output) | ||||
| } | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package jsoniter | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/modern-go/reflect2" | ||||
| 	"io" | ||||
| 	"reflect" | ||||
| 	"sort" | ||||
| 	"unsafe" | ||||
| @@ -107,6 +108,9 @@ func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder { | ||||
| 				stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), | ||||
| 			} | ||||
| 		} | ||||
| 		if typ.Kind() == reflect.Interface { | ||||
| 			return &dynamicMapKeyEncoder{ctx, typ} | ||||
| 		} | ||||
| 		return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)} | ||||
| 	} | ||||
| } | ||||
| @@ -203,6 +207,21 @@ func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| type dynamicMapKeyEncoder struct { | ||||
| 	ctx     *ctx | ||||
| 	valType reflect2.Type | ||||
| } | ||||
|  | ||||
| func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { | ||||
| 	obj := encoder.valType.UnsafeIndirect(ptr) | ||||
| 	encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream) | ||||
| } | ||||
|  | ||||
| func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { | ||||
| 	obj := encoder.valType.UnsafeIndirect(ptr) | ||||
| 	return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj)) | ||||
| } | ||||
|  | ||||
| type mapEncoder struct { | ||||
| 	mapType     *reflect2.UnsafeMapType | ||||
| 	keyEncoder  ValEncoder | ||||
| @@ -253,6 +272,9 @@ func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { | ||||
| 		subStream.buf = make([]byte, 0, 64) | ||||
| 		key, elem := mapIter.UnsafeNext() | ||||
| 		encoder.keyEncoder.Encode(key, subStream) | ||||
| 		if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil { | ||||
| 			stream.Error = subStream.Error | ||||
| 		} | ||||
| 		encodedKey := subStream.Buffer() | ||||
| 		subIter.ResetBytes(encodedKey) | ||||
| 		decodedKey := subIter.ReadString() | ||||
|   | ||||
| @@ -6,7 +6,7 @@ func init() { | ||||
| 		[]interface{}{"hello"}, | ||||
| 		nilSlice, | ||||
| 		&nilSlice, | ||||
| 		selectedMarshalCase{[]byte{1,2,3}}, | ||||
| 		[]byte{1, 2, 3}, | ||||
| 	) | ||||
| 	unmarshalCases = append(unmarshalCases, unmarshalCase{ | ||||
| 		ptr:   (*[]string)(nil), | ||||
| @@ -20,6 +20,5 @@ func init() { | ||||
| 	}, unmarshalCase{ | ||||
| 		ptr:   (*[]byte)(nil), | ||||
| 		input: `"aGVsbG8="`, | ||||
| 		selected: true, | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -4,8 +4,8 @@ import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"github.com/json-iterator/go" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 	"github.com/modern-go/reflect2" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user