You've already forked json-iterator
							
							
				mirror of
				https://github.com/json-iterator/go.git
				synced 2025-10-31 00:07:40 +02:00 
			
		
		
		
	support string conversion
This commit is contained in:
		| @@ -6,6 +6,7 @@ import ( | ||||
| 	"fmt" | ||||
| 	"unsafe" | ||||
| 	"sync/atomic" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| type Decoder interface { | ||||
| @@ -110,6 +111,24 @@ func (decoder *boolDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { | ||||
| 	*((*bool)(ptr)) = iter.ReadBool() | ||||
| } | ||||
|  | ||||
| type stringNumberDecoder struct { | ||||
| 	elemDecoder Decoder | ||||
| } | ||||
|  | ||||
| func (decoder *stringNumberDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { | ||||
| 	c := iter.readByte() | ||||
| 	if c != '"' { | ||||
| 		iter.ReportError("stringNumberDecoder", `expect "`) | ||||
| 		return | ||||
| 	} | ||||
| 	decoder.elemDecoder.decode(ptr, iter) | ||||
| 	c = iter.readByte() | ||||
| 	if c != '"' { | ||||
| 		iter.ReportError("stringNumberDecoder", `expect "`) | ||||
| 		return | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type optionalDecoder struct { | ||||
| 	valueType reflect.Type | ||||
| 	valueDecoder Decoder | ||||
| @@ -327,11 +346,21 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) { | ||||
| 	fields := map[string]Decoder{} | ||||
| 	for i := 0; i < type_.NumField(); i++ { | ||||
| 		field := type_.Field(i) | ||||
| 		tagParts := strings.Split(field.Tag.Get("json"), ",") | ||||
| 		jsonFieldName := tagParts[0] | ||||
| 		if jsonFieldName == "" { | ||||
| 			jsonFieldName = field.Name | ||||
| 		} | ||||
| 		decoder, err := decoderOfPtr(field.Type) | ||||
| 		if err != nil { | ||||
| 			return prefix(fmt.Sprintf("{%s}", field.Name)).addTo(decoder, err) | ||||
| 		} | ||||
| 		fields[field.Name] = &structFieldDecoder{field.Offset, decoder} | ||||
| 		if len(tagParts) > 1 && tagParts[1] == "string" { | ||||
| 			decoder = &stringNumberDecoder{decoder} | ||||
| 		} | ||||
| 		if jsonFieldName != "-" { | ||||
| 			fields[jsonFieldName] = &structFieldDecoder{field.Offset, decoder} | ||||
| 		} | ||||
| 	} | ||||
| 	return &structDecoder{fields}, nil | ||||
| } | ||||
|   | ||||
| @@ -187,9 +187,34 @@ func Test_reflect_struct_string_ptr(t *testing.T) { | ||||
| 		t.Fatal(struct_.field1) | ||||
| 	} | ||||
| 	if *struct_.field2 != "world" { | ||||
| 		fmt.Println(iter.Error) | ||||
| 		t.Fatal(struct_.field2) | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| type StructOfTag struct { | ||||
| 	field1 string `json:"field-1"` | ||||
| 	field2 string `json:"-"` | ||||
| 	field3 int `json:",string"` | ||||
| } | ||||
|  | ||||
| func Test_reflect_struct_tag_field(t *testing.T) { | ||||
| 	iter := ParseString(`{"field-1": "hello", "field2": "", "field3": "100"}`) | ||||
| 	struct_ := StructOfTag{field2: "world"} | ||||
| 	iter.Read(&struct_) | ||||
| 	if struct_.field1 != "hello" { | ||||
| 		fmt.Println(iter.Error) | ||||
| 		t.Fatal(struct_.field1) | ||||
| 	} | ||||
| 	if struct_.field2 != "world" { | ||||
| 		fmt.Println(iter.Error) | ||||
| 		t.Fatal(struct_.field2) | ||||
| 	} | ||||
| 	if struct_.field3 != 100 { | ||||
| 		fmt.Println(iter.Error) | ||||
| 		t.Fatal(struct_.field3) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Test_reflect_slice(t *testing.T) { | ||||
| @@ -235,12 +260,12 @@ func Test_reflect_nested(t *testing.T) { | ||||
| func Benchmark_jsoniter_reflect(b *testing.B) { | ||||
| 	b.ReportAllocs() | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		//iter := ParseString(`{"field1": "hello", "field2": "world"}`) | ||||
| 		//struct_ := StructOfString{} | ||||
| 		//iter.Read(&struct_) | ||||
| 		iter := ParseString(`["hello", "world"]`) | ||||
| 		array := make([]string, 0, 1) | ||||
| 		iter.Read(&array) | ||||
| 		iter := ParseString(`{"field3": "100"}`) | ||||
| 		struct_ := StructOfTag{} | ||||
| 		iter.Read(&struct_) | ||||
| 		//iter := ParseString(`["hello", "world"]`) | ||||
| 		//array := make([]string, 0, 1) | ||||
| 		//iter.Read(&array) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -270,9 +295,9 @@ func Benchmark_jsoniter_direct(b *testing.B) { | ||||
| func Benchmark_json_reflect(b *testing.B) { | ||||
| 	b.ReportAllocs() | ||||
| 	for n := 0; n < b.N; n++ { | ||||
| 		//struct_ := StructOfString{} | ||||
| 		//json.Unmarshal([]byte(`{"field1": "hello", "field2": "world"}`), &struct_) | ||||
| 		array := make([]string, 0, 2) | ||||
| 		json.Unmarshal([]byte(`["hello", "world"]`), &array) | ||||
| 		struct_ := StructOfTag{} | ||||
| 		json.Unmarshal([]byte(`{"field3": "100"}`), &struct_) | ||||
| 		//array := make([]string, 0, 2) | ||||
| 		//json.Unmarshal([]byte(`["hello", "world"]`), &array) | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user