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

     1  package typeTransform
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"reflect"
     7  	"strconv"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/bronze1man/kmg/kmgReflect"
    12  	"github.com/bronze1man/kmg/kmgStrconv"
    13  	"github.com/bronze1man/kmg/kmgTime"
    14  )
    15  
    16  /*
    17  try best transform one type to another type
    18  special case:
    19  "" => 0
    20  "" => 0.0
    21  */
    22  func Transform(in interface{}, out interface{}) (err error) {
    23  	return DefaultTransformer.Transform(in, out)
    24  }
    25  
    26  func MustTransform(in interface{}, out interface{}) {
    27  	err := DefaultTransformer.Transform(in, out)
    28  	if err != nil {
    29  		panic(err)
    30  	}
    31  }
    32  
    33  func MustTransformToMap(in interface{}) (m map[string]string) {
    34  	m = map[string]string{}
    35  	err := DefaultTransformer.Transform(in, &m)
    36  	if err != nil {
    37  		panic(err)
    38  	}
    39  	return m
    40  }
    41  
    42  func MapToMap(t Transformer, in reflect.Value, out reflect.Value) (err error) {
    43  	out.Set(reflect.MakeMap(out.Type()))
    44  	for _, key := range in.MapKeys() {
    45  		oKey := reflect.New(out.Type().Key()).Elem()
    46  		oVal := reflect.New(out.Type().Elem()).Elem()
    47  		err = t.Tran(key, oKey)
    48  		if err != nil {
    49  			return
    50  		}
    51  		val := in.MapIndex(key)
    52  		err = t.Tran(val, oVal)
    53  		if err != nil {
    54  			return
    55  		}
    56  		out.SetMapIndex(oKey, oVal)
    57  	}
    58  	return
    59  }
    60  
    61  func StringToString(t Transformer, in reflect.Value, out reflect.Value) (err error) {
    62  	out.SetString(in.String())
    63  	return nil
    64  }
    65  
    66  func NewStringToTimeFunc(location *time.Location) TransformerFunc {
    67  	return func(traner Transformer, in reflect.Value, out reflect.Value) (err error) {
    68  		var t time.Time
    69  		t, err = kmgTime.ParseAutoInLocation(in.String(), location)
    70  		if err != nil {
    71  			return
    72  		}
    73  		out.Set(reflect.ValueOf(t))
    74  		return
    75  	}
    76  }
    77  
    78  func StringToTime(traner Transformer, in reflect.Value, out reflect.Value) (err error) {
    79  	var t time.Time
    80  	t, err = kmgTime.ParseAutoInLocal(in.String())
    81  	if err != nil {
    82  		return
    83  	}
    84  	out.Set(reflect.ValueOf(t))
    85  	return
    86  }
    87  
    88  func TimeToString(traner Transformer, in reflect.Value, out reflect.Value) (err error) {
    89  	t := in.Interface().(time.Time)
    90  	out.SetString(t.In(kmgTime.DefaultTimeZone).Format(kmgTime.FormatMysql))
    91  	return nil
    92  }
    93  
    94  func PtrToPtr(t Transformer, in reflect.Value, out reflect.Value) (err error) {
    95  	return t.Tran(in.Elem(), out.Elem())
    96  }
    97  
    98  //假设map的key类型是string,值类型不限
    99  func MapToStruct(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   100  	oKey := reflect.New(reflect.TypeOf("")).Elem()
   101  	out.Set(reflect.New(out.Type()).Elem())
   102  	fieldNameMap := map[string]bool{}
   103  	for _, key := range in.MapKeys() {
   104  		err = t.Tran(key, oKey)
   105  		if err != nil {
   106  			return
   107  		}
   108  		sKey := oKey.String()
   109  		fieldNameMap[sKey] = true
   110  		oVal := out.FieldByName(sKey)
   111  		if !oVal.IsValid() {
   112  			continue
   113  		}
   114  		val := in.MapIndex(key)
   115  		err = t.Tran(val, oVal)
   116  		if err != nil {
   117  			return
   118  		}
   119  	}
   120  	return
   121  }
   122  
   123  //假设map的key类型是string,值类型不限
   124  func StructToMap(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   125  	oValType := out.Type().Elem()
   126  	oKey := reflect.New(reflect.TypeOf("")).Elem()
   127  	if out.IsNil() {
   128  		out.Set(reflect.MakeMap(out.Type())) //新建map不能使用reflect.New
   129  	}
   130  
   131  	fieldMap := kmgReflect.StructGetAllFieldMap(in.Type())
   132  	for key, field := range fieldMap {
   133  		if field.PkgPath != "" {
   134  			//忽略没有导出的字段
   135  			continue
   136  		}
   137  		iVal := in.FieldByName(key)
   138  		oVal := reflect.New(oValType).Elem()
   139  		err = t.Tran(iVal, oVal)
   140  		if err != nil {
   141  			return
   142  		}
   143  		oKey.SetString(key)
   144  		out.SetMapIndex(oKey, oVal)
   145  	}
   146  	return nil
   147  }
   148  
   149  func SliceToSlice(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   150  	len := in.Len()
   151  	out.Set(reflect.MakeSlice(out.Type(), len, len))
   152  	for i := 0; i < len; i++ {
   153  		val := in.Index(i)
   154  		err = t.Tran(val, out.Index(i))
   155  		if err != nil {
   156  			return
   157  		}
   158  	}
   159  	return
   160  }
   161  
   162  // "" => 0
   163  func StringToInt(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   164  	inS := in.String()
   165  	inS = strings.TrimSpace(inS)
   166  	if inS == "" {
   167  		out.SetInt(int64(0))
   168  		return nil
   169  	}
   170  	i, err := strconv.ParseInt(inS, 10, out.Type().Bits())
   171  	if err != nil {
   172  		return
   173  	}
   174  	out.SetInt(i)
   175  	return
   176  }
   177  
   178  // "" => 0
   179  func StringToUint(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   180  	inS := in.String()
   181  	inS = strings.TrimSpace(inS)
   182  	if inS == "" {
   183  		out.SetUint(uint64(0))
   184  		return nil
   185  	}
   186  	i, err := strconv.ParseUint(inS, 10, out.Type().Bits())
   187  	if err != nil {
   188  		return
   189  	}
   190  	out.SetUint(i)
   191  	return
   192  }
   193  
   194  // "" => 0.0
   195  func StringToFloat(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   196  	inS := in.String()
   197  	if inS == "" {
   198  		out.SetFloat(0.0)
   199  		return nil
   200  	}
   201  	i, err := strconv.ParseFloat(inS, out.Type().Bits())
   202  	if err != nil {
   203  		return
   204  	}
   205  	out.SetFloat(i)
   206  	return
   207  }
   208  
   209  // "" => false
   210  func StringToBool(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   211  	inS := in.String()
   212  	if inS == "" {
   213  		out.SetBool(false)
   214  		return nil
   215  	}
   216  	i, err := strconv.ParseBool(inS)
   217  	if err != nil {
   218  		return
   219  	}
   220  	out.SetBool(i)
   221  	return
   222  }
   223  
   224  func IntToInt(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   225  	out.SetInt(in.Int())
   226  	return nil
   227  }
   228  
   229  func FloatToInt(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   230  	outf1 := in.Float()
   231  	if math.Floor(outf1) != outf1 {
   232  		return fmt.Errorf("[typeTransform.tran] it seems to lose some accuracy trying to convert from float to int,float:%f", outf1)
   233  	}
   234  	out.SetInt(int64(outf1))
   235  	return
   236  }
   237  
   238  func FloatToFloat(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   239  	out.SetFloat(in.Float())
   240  	return
   241  }
   242  
   243  func FloatToString(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   244  	f := in.Float()
   245  	fs := kmgStrconv.FormatFloat(f)
   246  	out.SetString(fs)
   247  	return
   248  }
   249  
   250  func NonePtrToPtr(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   251  	if out.IsNil() {
   252  		out.Set(reflect.New(out.Type().Elem()))
   253  	}
   254  	return t.Tran(in, out.Elem())
   255  }
   256  func InterfaceToNoneInterface(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   257  	return t.Tran(in.Elem(), out)
   258  }
   259  func NoneInterfaceToInterface(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   260  	//满足interface的情况
   261  	if in.Type().Implements(out.Type()) {
   262  		out.Set(in)
   263  		return
   264  	}
   265  	return t.Tran(in, out.Elem())
   266  }
   267  
   268  func IntToString(t Transformer, in reflect.Value, out reflect.Value) (err error) {
   269  	s := strconv.FormatInt(in.Int(), 10)
   270  	out.SetString(s)
   271  	return nil
   272  }