github.com/andeya/ameda@v1.5.3/initialize.go (about)

     1  package ameda
     2  
     3  import (
     4  	"reflect"
     5  )
     6  
     7  // InitPointer initializes nil pointer with zero value.
     8  func InitPointer(v reflect.Value) (done bool) {
     9  	for {
    10  		kind := v.Kind()
    11  		if kind == reflect.Interface {
    12  			v = v.Elem()
    13  			continue
    14  		}
    15  		if kind != reflect.Ptr {
    16  			return true
    17  		}
    18  		u := v.Elem()
    19  		if u.IsValid() {
    20  			v = u
    21  			continue
    22  		}
    23  		if !v.CanSet() {
    24  			return false
    25  		}
    26  		v2 := reflect.New(v.Type().Elem())
    27  		v.Set(v2)
    28  		v = v.Elem()
    29  	}
    30  }
    31  
    32  // InitString initializes empty string pointer with def.
    33  func InitString(p *string, def string) (done bool) {
    34  	if p == nil {
    35  		return false
    36  	}
    37  	if *p == "" {
    38  		*p = def
    39  	}
    40  	return true
    41  }
    42  
    43  // InitBool initializes false bool pointer with def.
    44  func InitBool(p *bool, def bool) (done bool) {
    45  	if p == nil {
    46  		return false
    47  	}
    48  	if *p == false {
    49  		*p = def
    50  	}
    51  	return true
    52  }
    53  
    54  // InitByte initializes zero byte pointer with def.
    55  func InitByte(p *byte, def byte) (done bool) {
    56  	if p == nil {
    57  		return false
    58  	}
    59  	if *p == 0 {
    60  		*p = def
    61  	}
    62  	return true
    63  }
    64  
    65  // InitInt initializes zero int pointer with def.
    66  func InitInt(p *int, def int) (done bool) {
    67  	if p == nil {
    68  		return false
    69  	}
    70  	if *p == 0 {
    71  		*p = def
    72  	}
    73  	return true
    74  }
    75  
    76  // InitInt8 initializes zero int8 pointer with def.
    77  func InitInt8(p *int8, def int8) (done bool) {
    78  	if p == nil {
    79  		return false
    80  	}
    81  	if *p == 0 {
    82  		*p = def
    83  	}
    84  	return true
    85  }
    86  
    87  // InitInt16 initializes zero int16 pointer with def.
    88  func InitInt16(p *int16, def int16) (done bool) {
    89  	if p == nil {
    90  		return false
    91  	}
    92  	if *p == 0 {
    93  		*p = def
    94  	}
    95  	return true
    96  }
    97  
    98  // InitInt32 initializes zero int32 pointer with def.
    99  func InitInt32(p *int32, def int32) (done bool) {
   100  	if p == nil {
   101  		return false
   102  	}
   103  	if *p == 0 {
   104  		*p = def
   105  	}
   106  	return true
   107  }
   108  
   109  // InitInt64 initializes zero int64 pointer with def.
   110  func InitInt64(p *int64, def int64) (done bool) {
   111  	if p == nil {
   112  		return false
   113  	}
   114  	if *p == 0 {
   115  		*p = def
   116  	}
   117  	return true
   118  }
   119  
   120  // InitUint initializes zero uint pointer with def.
   121  func InitUint(p *uint, def uint) (done bool) {
   122  	if p == nil {
   123  		return false
   124  	}
   125  	if *p == 0 {
   126  		*p = def
   127  	}
   128  	return true
   129  }
   130  
   131  // InitUint8 initializes zero uint8 pointer with def.
   132  func InitUint8(p *uint8, def uint8) (done bool) {
   133  	if p == nil {
   134  		return false
   135  	}
   136  	if *p == 0 {
   137  		*p = def
   138  	}
   139  	return true
   140  }
   141  
   142  // InitUint16 initializes zero uint16 pointer with def.
   143  func InitUint16(p *uint16, def uint16) (done bool) {
   144  	if p == nil {
   145  		return false
   146  	}
   147  	if *p == 0 {
   148  		*p = def
   149  	}
   150  	return true
   151  }
   152  
   153  // InitUint32 initializes zero uint32 pointer with def.
   154  func InitUint32(p *uint32, def uint32) (done bool) {
   155  	if p == nil {
   156  		return false
   157  	}
   158  	if *p == 0 {
   159  		*p = def
   160  	}
   161  	return true
   162  }
   163  
   164  // InitUint64 initializes zero uint64 pointer with def.
   165  func InitUint64(p *uint64, def uint64) (done bool) {
   166  	if p == nil {
   167  		return false
   168  	}
   169  	if *p == 0 {
   170  		*p = def
   171  	}
   172  	return true
   173  }
   174  
   175  // InitFloat32 initializes zero float32 pointer with def.
   176  func InitFloat32(p *float32, def float32) (done bool) {
   177  	if p == nil {
   178  		return false
   179  	}
   180  	if *p == 0 {
   181  		*p = def
   182  	}
   183  	return true
   184  }
   185  
   186  // InitFloat64 initializes zero float64 pointer with def.
   187  func InitFloat64(p *float64, def float64) (done bool) {
   188  	if p == nil {
   189  		return false
   190  	}
   191  	if *p == 0 {
   192  		*p = def
   193  	}
   194  	return true
   195  }
   196  
   197  // InitSampleValue initialize the given type with some non-zero value( "?", $max_number, 0.1, true)
   198  func InitSampleValue(t reflect.Type, maxNestingDeep int) reflect.Value {
   199  	if maxNestingDeep <= 0 {
   200  		maxNestingDeep = 10
   201  	}
   202  	ptrDepth := 0
   203  	for t.Kind() == reflect.Ptr {
   204  		t = t.Elem()
   205  		ptrDepth++
   206  	}
   207  	v := reflect.New(t)
   208  	v = initValue(v, 1, maxNestingDeep)
   209  	return ReferenceValue(v, ptrDepth-1)
   210  }
   211  
   212  func initValue(v reflect.Value, curDeep int, maxDeep int) reflect.Value {
   213  	InitPointer(v)
   214  	if curDeep >= maxDeep {
   215  		return v
   216  	}
   217  	var numPtr int
   218  	for v.Kind() == reflect.Ptr {
   219  		v = v.Elem()
   220  		numPtr++
   221  	}
   222  	if v.CanSet() {
   223  		switch v.Kind() {
   224  		case reflect.Struct:
   225  			curDeep++
   226  			fieldNum := v.Type().NumField()
   227  			for i := 0; i < fieldNum; i++ {
   228  				e := v.Field(i)
   229  				InitPointer(e)
   230  				if e.CanSet() {
   231  					e.Set(initValue(e, curDeep, maxDeep))
   232  				}
   233  			}
   234  		case reflect.Slice:
   235  			if v.Len() == 0 {
   236  				e := reflect.New(v.Type().Elem())
   237  				InitPointer(e)
   238  				e = e.Elem()
   239  				e = initValue(e, curDeep, maxDeep)
   240  				if v.CanSet() {
   241  					v.Set(reflect.Append(v, e))
   242  				}
   243  			}
   244  		case reflect.Array:
   245  			if v.Len() > 0 {
   246  				e := reflect.New(v.Type().Elem())
   247  				InitPointer(e)
   248  				e = e.Elem()
   249  				e = initValue(e, curDeep, maxDeep)
   250  				vv := v.Index(0)
   251  				if vv.CanSet() {
   252  					vv.Set(reflect.Append(v, e))
   253  				}
   254  			}
   255  		case reflect.Map:
   256  			if v.Len() == 0 {
   257  				v.Set(reflect.MakeMap(v.Type()))
   258  				k := reflect.New(v.Type().Key())
   259  				InitPointer(k)
   260  				k = k.Elem()
   261  				k = initValue(k, curDeep, maxDeep)
   262  				e := reflect.New(v.Type().Elem())
   263  				InitPointer(e)
   264  				e = e.Elem()
   265  				e = initValue(e, curDeep, maxDeep)
   266  				v.SetMapIndex(k, e)
   267  			}
   268  		case reflect.Int:
   269  			if Host32bit {
   270  				v.SetInt(-32)
   271  			} else {
   272  				v.SetInt(-64)
   273  			}
   274  		case reflect.Int8:
   275  			v.SetInt(-8)
   276  		case reflect.Int16:
   277  			v.SetInt(-16)
   278  		case reflect.Int32:
   279  			v.SetInt(-32)
   280  		case reflect.Int64:
   281  			v.SetInt(-64)
   282  		case reflect.Uint, reflect.Uintptr:
   283  			if Host32bit {
   284  				v.SetUint(32)
   285  			} else {
   286  				v.SetUint(64)
   287  			}
   288  		case reflect.Uint8:
   289  			v.SetUint(8)
   290  		case reflect.Uint16:
   291  			v.SetUint(16)
   292  		case reflect.Uint32:
   293  			v.SetUint(32)
   294  		case reflect.Uint64:
   295  			v.SetUint(64)
   296  		case reflect.Float32:
   297  			v.SetFloat(-0.32)
   298  		case reflect.Float64:
   299  			v.SetFloat(-0.64)
   300  		case reflect.Bool:
   301  			v.SetBool(true)
   302  		case reflect.String:
   303  			v.SetString("?")
   304  		default:
   305  		}
   306  	}
   307  	return ReferenceValue(v, numPtr)
   308  }