Tao Wen 9 rokov pred
rodič
commit
7d5f2aed7b
3 zmenil súbory, kde vykonal 42 pridanie a 10 odobranie
  1. 1 1
      README.md
  2. 26 2
      jsoniter_customize_test.go
  3. 15 7
      jsoniter_reflect.go

+ 1 - 1
README.md

@@ -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
 

+ 26 - 2
jsoniter_customize_test.go

@@ -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)
+	}
 }

+ 15 - 7
jsoniter_reflect.go

@@ -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
 			}