You've already forked json-iterator
							
							
				mirror of
				https://github.com/json-iterator/go.git
				synced 2025-10-31 00:07:40 +02:00 
			
		
		
		
	update extension
This commit is contained in:
		| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
| 	} | ||||
| } | ||||
| @@ -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 | ||||
| 			} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user