github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/typeTransform/Transformer.go (about)

     1  package typeTransform
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  
     7  	"github.com/bronze1man/kmg/kmgTime"
     8  	"github.com/bronze1man/kmg/kmgType"
     9  )
    10  
    11  //golang的kind分的太细
    12  type Kind uint
    13  
    14  const (
    15  	Invalid Kind = iota
    16  	String
    17  	Int
    18  	Float
    19  	Ptr
    20  	Bool
    21  	Time
    22  	Interface
    23  	Map
    24  	Struct
    25  	Slice
    26  	Array
    27  	Uint
    28  )
    29  
    30  func (k Kind) String() string {
    31  	switch k {
    32  	case Invalid:
    33  		return "Invalid"
    34  	case String:
    35  		return "String"
    36  	case Int:
    37  		return "Int"
    38  	case Float:
    39  		return "Float"
    40  	case Ptr:
    41  		return "Ptr"
    42  	case Bool:
    43  		return "Bool"
    44  	case Time:
    45  		return "Time"
    46  	case Interface:
    47  		return "Interface"
    48  	case Map:
    49  		return "Map"
    50  	case Struct:
    51  		return "Struct"
    52  	case Slice:
    53  		return "Slice"
    54  	case Array:
    55  		return "Array"
    56  	case Uint:
    57  		return "Uint"
    58  	default:
    59  		return fmt.Sprintf("Kind: not defined %d", k)
    60  	}
    61  }
    62  
    63  type TransformerFunc func(traner Transformer, in reflect.Value, out reflect.Value) (err error)
    64  type Transformer map[Kind]map[Kind]TransformerFunc
    65  
    66  func (t Transformer) Transform(in interface{}, out interface{}) (err error) {
    67  	return t.Tran(reflect.ValueOf(in), reflect.ValueOf(out))
    68  }
    69  func (t Transformer) Tran(in reflect.Value, out reflect.Value) (err error) {
    70  	iKind := GetReflectKind(in)
    71  	oKind := GetReflectKind(out)
    72  
    73  	//	fmt.Println(iKind,oKind,in.Type().String(),out.Type().String())
    74  	m1, ok := t[iKind]
    75  	if !ok {
    76  		return fmt.Errorf("[typeTransform.tran] not support tran kind: [%s] to [%s]", in.Kind(), out.Kind())
    77  	}
    78  	m2, ok := m1[oKind]
    79  	if !ok {
    80  		return fmt.Errorf("[typeTransform.tran] not support tran kind: [%s] to [%s]", in.Kind(), out.Kind())
    81  	}
    82  	return m2(t, in, out)
    83  }
    84  func (t Transformer) Clone() Transformer {
    85  	out1 := Transformer{}
    86  	for inKind, m1 := range t {
    87  		out2 := map[Kind]TransformerFunc{}
    88  		for outKind, m2 := range m1 {
    89  			out2[outKind] = m2
    90  		}
    91  		out1[inKind] = out2
    92  	}
    93  	return out1
    94  }
    95  func GetReflectKind(in reflect.Value) Kind {
    96  	t := in.Type()
    97  	if t == kmgType.DateTimeReflectType {
    98  		return Time
    99  	}
   100  	switch t.Kind() {
   101  	case reflect.String:
   102  		return String
   103  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   104  		return Int
   105  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
   106  		reflect.Uintptr:
   107  		return Uint
   108  	case reflect.Float32, reflect.Float64:
   109  		return Float
   110  	case reflect.Ptr:
   111  		return Ptr
   112  	case reflect.Bool:
   113  		return Bool
   114  	case reflect.Interface:
   115  		return Interface
   116  	case reflect.Map:
   117  		return Map
   118  	case reflect.Struct:
   119  		return Struct
   120  	case reflect.Slice:
   121  		return Slice
   122  	case reflect.Array:
   123  		return Array
   124  	}
   125  	panic(fmt.Errorf("not implement type %s", t.Kind().String()))
   126  }
   127  
   128  var DefaultTransformer = Transformer{
   129  	Map: map[Kind]TransformerFunc{
   130  		Map:       MapToMap,
   131  		Struct:    MapToStruct,
   132  		Ptr:       NonePtrToPtr,
   133  		Interface: NoneInterfaceToInterface,
   134  	},
   135  	String: map[Kind]TransformerFunc{
   136  		String:    StringToString,
   137  		Int:       StringToInt,
   138  		Uint:      StringToUint,
   139  		Float:     StringToFloat,
   140  		Bool:      StringToBool,
   141  		Time:      NewStringToTimeFunc(kmgTime.DefaultTimeZone),
   142  		Ptr:       NonePtrToPtr,
   143  		Interface: NoneInterfaceToInterface,
   144  	},
   145  	Ptr: map[Kind]TransformerFunc{
   146  		Ptr: PtrToPtr, //TODO reference to self..
   147  	},
   148  	Struct: map[Kind]TransformerFunc{
   149  		Map:       StructToMap,
   150  		Ptr:       NonePtrToPtr,
   151  		Interface: NoneInterfaceToInterface,
   152  	},
   153  	Slice: map[Kind]TransformerFunc{
   154  		Slice:     SliceToSlice,
   155  		Ptr:       NonePtrToPtr,
   156  		Interface: NoneInterfaceToInterface,
   157  	},
   158  	Interface: map[Kind]TransformerFunc{
   159  		String: InterfaceToNoneInterface,
   160  		Int:    InterfaceToNoneInterface,
   161  		Float:  InterfaceToNoneInterface,
   162  		Bool:   InterfaceToNoneInterface,
   163  		Time:   InterfaceToNoneInterface,
   164  		Struct: InterfaceToNoneInterface,
   165  		Map:    InterfaceToNoneInterface,
   166  		Ptr:    InterfaceToNoneInterface,
   167  	},
   168  	Int: map[Kind]TransformerFunc{
   169  		String:    IntToString,
   170  		Int:       IntToInt,
   171  		Ptr:       NonePtrToPtr,
   172  		Interface: NoneInterfaceToInterface,
   173  	},
   174  	Float: map[Kind]TransformerFunc{
   175  		Int:       FloatToInt,
   176  		Float:     FloatToFloat,
   177  		Ptr:       NonePtrToPtr,
   178  		String:    FloatToString,
   179  		Interface: NoneInterfaceToInterface,
   180  	},
   181  	Time: map[Kind]TransformerFunc{
   182  		String:    TimeToString,
   183  		Ptr:       NonePtrToPtr,
   184  		Interface: NoneInterfaceToInterface,
   185  	},
   186  }