github.com/gogf/gf/v2@v2.7.4/util/gconv/internal/structcache/structcache.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  // Package structcache provides struct and field info cache feature to enhance performance for struct converting.
     8  package structcache
     9  
    10  import (
    11  	"reflect"
    12  
    13  	"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
    14  )
    15  
    16  var (
    17  	// customConvertTypeMap is used to store whether field types are registered to custom conversions
    18  	// For example:
    19  	// func (src *TypeA) (dst *TypeB,err error)
    20  	// This map will store `TypeB` for quick judgment during assignment.
    21  	customConvertTypeMap = map[reflect.Type]struct{}{}
    22  )
    23  
    24  // RegisterCustomConvertType registers custom
    25  func RegisterCustomConvertType(fieldType reflect.Type) {
    26  	if fieldType.Kind() == reflect.Ptr {
    27  		fieldType = fieldType.Elem()
    28  	}
    29  	customConvertTypeMap[fieldType] = struct{}{}
    30  }
    31  
    32  var (
    33  	implUnmarshalText  = reflect.TypeOf((*localinterface.IUnmarshalText)(nil)).Elem()
    34  	implUnmarshalJson  = reflect.TypeOf((*localinterface.IUnmarshalJSON)(nil)).Elem()
    35  	implUnmarshalValue = reflect.TypeOf((*localinterface.IUnmarshalValue)(nil)).Elem()
    36  )
    37  
    38  func checkTypeIsCommonInterface(field reflect.StructField) bool {
    39  	isCommonInterface := false
    40  	switch field.Type.String() {
    41  	case "time.Time", "*time.Time":
    42  		// default convert.
    43  
    44  	case "gtime.Time", "*gtime.Time":
    45  		// default convert.
    46  
    47  	default:
    48  		// Implemented three types of interfaces that must be pointer types, otherwise it is meaningless
    49  		if field.Type.Kind() != reflect.Ptr {
    50  			field.Type = reflect.PointerTo(field.Type)
    51  		}
    52  		switch {
    53  		case field.Type.Implements(implUnmarshalText):
    54  			isCommonInterface = true
    55  
    56  		case field.Type.Implements(implUnmarshalJson):
    57  			isCommonInterface = true
    58  
    59  		case field.Type.Implements(implUnmarshalValue):
    60  			isCommonInterface = true
    61  		}
    62  	}
    63  	return isCommonInterface
    64  }