gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

zerochecker.go (2251B)


      1 package schema
      2 
      3 import (
      4 	"database/sql/driver"
      5 	"reflect"
      6 )
      7 
      8 var isZeroerType = reflect.TypeOf((*isZeroer)(nil)).Elem()
      9 
     10 type isZeroer interface {
     11 	IsZero() bool
     12 }
     13 
     14 type IsZeroerFunc func(reflect.Value) bool
     15 
     16 func zeroChecker(typ reflect.Type) IsZeroerFunc {
     17 	if typ.Implements(isZeroerType) {
     18 		return isZeroInterface
     19 	}
     20 
     21 	kind := typ.Kind()
     22 
     23 	if kind != reflect.Ptr {
     24 		ptr := reflect.PtrTo(typ)
     25 		if ptr.Implements(isZeroerType) {
     26 			return addrChecker(isZeroInterface)
     27 		}
     28 	}
     29 
     30 	switch kind {
     31 	case reflect.Array:
     32 		if typ.Elem().Kind() == reflect.Uint8 {
     33 			return isZeroBytes
     34 		}
     35 		return isZeroLen
     36 	case reflect.String:
     37 		return isZeroLen
     38 	case reflect.Bool:
     39 		return isZeroBool
     40 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
     41 		return isZeroInt
     42 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
     43 		return isZeroUint
     44 	case reflect.Float32, reflect.Float64:
     45 		return isZeroFloat
     46 	case reflect.Interface, reflect.Ptr, reflect.Slice, reflect.Map:
     47 		return isNil
     48 	}
     49 
     50 	if typ.Implements(driverValuerType) {
     51 		return isZeroDriverValue
     52 	}
     53 
     54 	return notZero
     55 }
     56 
     57 func addrChecker(fn IsZeroerFunc) IsZeroerFunc {
     58 	return func(v reflect.Value) bool {
     59 		if !v.CanAddr() {
     60 			return false
     61 		}
     62 		return fn(v.Addr())
     63 	}
     64 }
     65 
     66 func isZeroInterface(v reflect.Value) bool {
     67 	if v.Kind() == reflect.Ptr && v.IsNil() {
     68 		return true
     69 	}
     70 	return v.Interface().(isZeroer).IsZero()
     71 }
     72 
     73 func isZeroDriverValue(v reflect.Value) bool {
     74 	if v.Kind() == reflect.Ptr {
     75 		return v.IsNil()
     76 	}
     77 
     78 	valuer := v.Interface().(driver.Valuer)
     79 	value, err := valuer.Value()
     80 	if err != nil {
     81 		return false
     82 	}
     83 	return value == nil
     84 }
     85 
     86 func isZeroLen(v reflect.Value) bool {
     87 	return v.Len() == 0
     88 }
     89 
     90 func isNil(v reflect.Value) bool {
     91 	return v.IsNil()
     92 }
     93 
     94 func isZeroBool(v reflect.Value) bool {
     95 	return !v.Bool()
     96 }
     97 
     98 func isZeroInt(v reflect.Value) bool {
     99 	return v.Int() == 0
    100 }
    101 
    102 func isZeroUint(v reflect.Value) bool {
    103 	return v.Uint() == 0
    104 }
    105 
    106 func isZeroFloat(v reflect.Value) bool {
    107 	return v.Float() == 0
    108 }
    109 
    110 func isZeroBytes(v reflect.Value) bool {
    111 	b := v.Slice(0, v.Len()).Bytes()
    112 	for _, c := range b {
    113 		if c != 0 {
    114 			return false
    115 		}
    116 	}
    117 	return true
    118 }
    119 
    120 func notZero(v reflect.Value) bool {
    121 	return false
    122 }