1
0
mirror of https://github.com/json-iterator/go.git synced 2024-11-27 08:30:57 +02:00

update extension

This commit is contained in:
Tao Wen 2016-12-17 17:38:13 +08:00
parent d0f45c663f
commit 7d5f2aed7b
3 changed files with 42 additions and 10 deletions

View File

@ -54,7 +54,7 @@ val := iter.ReadAny()
fmt.Println(val.ToInt(1, "field2")) // 22
```
Notice you can extract from nested data structure, and convert any type to the type to you want.
Notice you can extract from nested data structure, and convert any type to the type to you want.
# How to get

View File

@ -45,8 +45,8 @@ func Test_customize_field_decoder(t *testing.T) {
}
}
func Test_customize_field_decoder_factory(t *testing.T) {
RegisterFieldCustomizer(func(type_ reflect.Type, field *reflect.StructField) ([]string, DecoderFunc) {
func Test_customize_field_by_extension(t *testing.T) {
RegisterExtension(func(type_ reflect.Type, field *reflect.StructField) ([]string, DecoderFunc) {
if (type_.String() == "jsoniter.Tom" && field.Name == "field1") {
return []string{"field-1"}, func(ptr unsafe.Pointer, iter *Iterator) {
*((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
@ -62,4 +62,28 @@ func Test_customize_field_decoder_factory(t *testing.T) {
if tom.field1 != "100" {
t.Fatal(tom.field1)
}
}
type Jerry struct {
field1 string
}
func Test_customize_type_by_extension(t *testing.T) {
RegisterExtension(func(type_ reflect.Type, field *reflect.StructField) ([]string, DecoderFunc) {
if (type_.String() == "jsoniter.Jerry" && field == nil) {
return nil, func(ptr unsafe.Pointer, iter *Iterator) {
obj := (*Jerry)(ptr)
obj.field1 = iter.ReadString()
}
}
return nil, nil
})
jerry := Jerry{}
err := Unmarshal([]byte(`"100"`), &jerry)
if err != nil {
t.Fatal(err)
}
if jerry.field1 != "100" {
t.Fatal(jerry.field1)
}
}

View File

@ -450,17 +450,17 @@ func getDecoderFromCache(cacheKey reflect.Type) Decoder {
var typeDecoders map[string]Decoder
var fieldDecoders map[string]Decoder
var fieldCustomizers []FieldCustomizerFunc
var extensions []ExtensionFunc
func init() {
typeDecoders = map[string]Decoder{}
fieldDecoders = map[string]Decoder{}
fieldCustomizers = []FieldCustomizerFunc{}
extensions = []ExtensionFunc{}
atomic.StorePointer(&DECODERS, unsafe.Pointer(&map[string]Decoder{}))
}
type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator)
type FieldCustomizerFunc func(type_ reflect.Type, field *reflect.StructField) ([]string, DecoderFunc)
type ExtensionFunc func(type_ reflect.Type, field *reflect.StructField) ([]string, DecoderFunc)
type funcDecoder struct {
func_ DecoderFunc
@ -478,8 +478,8 @@ func RegisterFieldDecoder(type_ string, field string, func_ DecoderFunc) {
fieldDecoders[fmt.Sprintf("%s/%s", type_, field)] = &funcDecoder{func_}
}
func RegisterFieldCustomizer(func_ FieldCustomizerFunc) {
fieldCustomizers = append(fieldCustomizers, func_)
func RegisterExtension(extension ExtensionFunc) {
extensions = append(extensions, extension)
}
func ClearDecoders() {
@ -632,6 +632,14 @@ func decoderOfPtr(type_ reflect.Type) (Decoder, error) {
if typeName == "jsoniter.Any" {
return &anyDecoder{}, nil
}
for _, extension := range extensions {
alternativeFieldNames, func_ := extension(type_, nil)
if alternativeFieldNames != nil {
return nil, fmt.Errorf("%v should not return alternative field names when only type is being passed", extension)
}
typeDecoders[typeName] = &funcDecoder{func_}
}
typeDecoder := typeDecoders[typeName]
if typeDecoder != nil {
return typeDecoder, nil
@ -694,8 +702,8 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) {
field := type_.Field(i)
fieldDecoderKey := fmt.Sprintf("%s/%s", type_.String(), field.Name)
var fieldNames []string
for _, customizer := range fieldCustomizers {
alternativeFieldNames, func_ := customizer(type_, &field)
for _, extension := range extensions {
alternativeFieldNames, func_ := extension(type_, &field)
if alternativeFieldNames != nil {
fieldNames = alternativeFieldNames
}