mirror of
https://github.com/json-iterator/go.git
synced 2025-03-20 20:54:55 +02:00
support string conversion
This commit is contained in:
parent
d8153db791
commit
d80d954345
@ -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)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user