Skip to content

Commit

Permalink
random Make allow empty interface values and subtypes
Browse files Browse the repository at this point in the history
  • Loading branch information
adamluzsi committed Jun 14, 2023
1 parent c7e6010 commit a0437ef
Show file tree
Hide file tree
Showing 3 changed files with 338 additions and 72 deletions.
131 changes: 64 additions & 67 deletions random/Factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ type Factory struct {

type (
typeFunc func(r *Random) any
kindFunc func(r *Random, T interface{}) any
kindFunc func(r *Random, T reflect.Type) any
)

func (f *Factory) Make(rnd *Random, T any) (_T any) {
if T == nil {
panic(`nil is not accepted value type`)
return nil
}
rt := reflect.TypeOf(T)
if typeFunc, ok := f.getTypes()[rt]; ok {
return typeFunc(rnd)
}
if kindFunc, ok := f.getKinds()[rt.Kind()]; ok {
return kindFunc(rnd, T)
return kindFunc(rnd, reflect.TypeOf(T))
}
return T
}
Expand All @@ -44,21 +44,6 @@ func (f *Factory) RegisterType(T any, ff typeFunc) {
func (f *Factory) getTypes() map[reflect.Type]typeFunc {
f.types.init.Do(func() {
f.types.mapping = make(map[reflect.Type]typeFunc)
f.types.mapping[reflect.TypeOf(int(0))] = f.int
f.types.mapping[reflect.TypeOf(int8(0))] = f.int8
f.types.mapping[reflect.TypeOf(int16(0))] = f.int16
f.types.mapping[reflect.TypeOf(int32(0))] = f.int32
f.types.mapping[reflect.TypeOf(int64(0))] = f.int64
f.types.mapping[reflect.TypeOf(uint(0))] = f.uint
f.types.mapping[reflect.TypeOf(uint8(0))] = f.uint8
f.types.mapping[reflect.TypeOf(uint16(0))] = f.uint16
f.types.mapping[reflect.TypeOf(uint32(0))] = f.uint32
f.types.mapping[reflect.TypeOf(uint64(0))] = f.uint64
f.types.mapping[reflect.TypeOf(float32(0))] = f.float32
f.types.mapping[reflect.TypeOf(float64(0))] = f.float64
f.types.mapping[reflect.TypeOf(uintptr(0))] = f.uintptr
f.types.mapping[reflect.TypeOf(string(""))] = f.string
f.types.mapping[reflect.TypeOf(bool(false))] = f.bool
f.types.mapping[reflect.TypeOf(time.Time{})] = f.timeTime
f.types.mapping[reflect.TypeOf(time.Duration(0))] = f.timeDuration
})
Expand All @@ -69,56 +54,56 @@ func (f *Factory) getRandom() *Random {
return New(CryptoSeed{})
}

func (f *Factory) int(rnd *Random) any {
return rnd.Int()
func (f *Factory) int(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(rnd.Int()).Convert(T).Interface()
}

func (f *Factory) int8(rnd *Random) any {
return int8(rnd.Int())
func (f *Factory) int8(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(int8(rnd.Int())).Convert(T).Interface()
}

func (f *Factory) int16(rnd *Random) any {
return int16(rnd.Int())
func (f *Factory) int16(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(int16(rnd.Int())).Convert(T).Interface()
}

func (f *Factory) int32(rnd *Random) any {
return int32(rnd.Int())
func (f *Factory) int32(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(int32(rnd.Int())).Convert(T).Interface()
}

func (f *Factory) int64(rnd *Random) any {
return int64(rnd.Int())
func (f *Factory) int64(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(int64(rnd.Int())).Convert(T).Interface()
}

func (f *Factory) uint(rnd *Random) any {
return uint(rnd.Int())
func (f *Factory) uint(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(uint(rnd.Int())).Convert(T).Interface()
}

func (f *Factory) uint8(rnd *Random) any {
return uint8(rnd.Int())
func (f *Factory) uint8(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(uint8(rnd.Int())).Convert(T).Interface()
}

func (f *Factory) uint16(rnd *Random) any {
return uint16(rnd.Int())
func (f *Factory) uint16(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(uint16(rnd.Int())).Convert(T).Interface()
}

func (f *Factory) uint32(rnd *Random) any {
return uint32(rnd.Int())
func (f *Factory) uint32(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(uint32(rnd.Int())).Convert(T).Interface()
}

func (f *Factory) uint64(rnd *Random) any {
return uint64(rnd.Int())
func (f *Factory) uint64(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(uint64(rnd.Int())).Convert(T).Interface()
}

func (f *Factory) float32(rnd *Random) any {
return rnd.Float32()
func (f *Factory) float32(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(rnd.Float32()).Convert(T).Interface()
}

func (f *Factory) float64(rnd *Random) any {
return rnd.Float64()
func (f *Factory) float64(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(rnd.Float64()).Convert(T).Interface()
}

func (f *Factory) uintptr(rnd *Random) any {
return uintptr(rnd.Int())
func (f *Factory) uintptr(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(uintptr(rnd.Int())).Convert(T).Interface()
}

func (f *Factory) timeTime(rnd *Random) any {
Expand All @@ -129,12 +114,12 @@ func (f *Factory) timeDuration(rnd *Random) any {
return time.Duration(rnd.IntBetween(int(time.Second), math.MaxInt32))
}

func (f *Factory) bool(rnd *Random) any {
return rnd.Bool()
func (f *Factory) bool(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(rnd.Bool()).Convert(T).Interface()
}

func (f *Factory) string(rnd *Random) any {
return rnd.String()
func (f *Factory) string(rnd *Random, T reflect.Type) any {
return reflect.ValueOf(rnd.String()).Convert(T).Interface()
}

func (f *Factory) getKinds() map[reflect.Kind]kindFunc {
Expand All @@ -146,12 +131,27 @@ func (f *Factory) getKinds() map[reflect.Kind]kindFunc {
f.kinds.mapping[reflect.Slice] = f.kindSlice
f.kinds.mapping[reflect.Array] = f.kindArray
f.kinds.mapping[reflect.Chan] = f.kindChan
f.kinds.mapping[reflect.Int] = f.int
f.kinds.mapping[reflect.Int8] = f.int8
f.kinds.mapping[reflect.Int16] = f.int16
f.kinds.mapping[reflect.Int32] = f.int32
f.kinds.mapping[reflect.Int64] = f.int64
f.kinds.mapping[reflect.Uint] = f.uint
f.kinds.mapping[reflect.Uint8] = f.uint8
f.kinds.mapping[reflect.Uint16] = f.uint16
f.kinds.mapping[reflect.Uint32] = f.uint32
f.kinds.mapping[reflect.Uint64] = f.uint64
f.kinds.mapping[reflect.Float32] = f.float32
f.kinds.mapping[reflect.Float64] = f.float64
f.kinds.mapping[reflect.Uintptr] = f.uintptr
f.kinds.mapping[reflect.String] = f.string
f.kinds.mapping[reflect.Bool] = f.bool
})
return f.kinds.mapping
}

func (f *Factory) kindStruct(rnd *Random, T any) any {
rStruct := reflect.New(reflect.TypeOf(T)).Elem()
func (f *Factory) kindStruct(rnd *Random, T reflect.Type) any {
rStruct := reflect.New(T).Elem()
numField := rStruct.NumField()
for i := 0; i < numField; i++ {
field := rStruct.Field(i)
Expand All @@ -166,57 +166,54 @@ func (f *Factory) kindStruct(rnd *Random, T any) any {
return rStruct.Interface()
}

func (f *Factory) kindPtr(rnd *Random, T any) any {
ptr := reflect.New(reflect.TypeOf(T).Elem()) // new ptr
func (f *Factory) kindPtr(rnd *Random, T reflect.Type) any {
ptr := reflect.New(T.Elem()) // new ptr
elemT := reflect.New(ptr.Type().Elem()).Elem().Interface() // new ptr value
value := f.Make(rnd, elemT)
ptr.Elem().Set(reflect.ValueOf(value)) // set ptr with a value
return ptr.Interface()
}

func (f *Factory) kindMap(rnd *Random, T any) any {
rt := reflect.TypeOf(T)
rv := reflect.MakeMap(rt)
func (f *Factory) kindMap(rnd *Random, T reflect.Type) any {
rv := reflect.MakeMap(T)

total := rnd.IntN(7)
for i := 0; i < total; i++ {
key := f.Make(rnd, reflect.New(rt.Key()).Elem().Interface())
value := f.Make(rnd, reflect.New(rt.Elem()).Elem().Interface())
key := f.Make(rnd, reflect.New(T.Key()).Elem().Interface())
value := f.Make(rnd, reflect.New(T.Elem()).Elem().Interface())
rv.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(value))
}

return rv.Interface()
}

func (f *Factory) kindSlice(rnd *Random, T any) any {
func (f *Factory) kindSlice(rnd *Random, T reflect.Type) any {
var (
rtype = reflect.TypeOf(T)
rslice = reflect.MakeSlice(rtype, 0, 0)
rslice = reflect.MakeSlice(T, 0, 0)
total = rnd.IntN(7)
values []reflect.Value
)
for i := 0; i < total; i++ {
v := f.Make(rnd, reflect.New(rtype.Elem()).Elem().Interface())
v := f.Make(rnd, reflect.New(T.Elem()).Elem().Interface())
values = append(values, reflect.ValueOf(v))
}

rslice = reflect.Append(rslice, values...)
return rslice.Interface()
}

func (f *Factory) kindArray(rnd *Random, T any) any {
func (f *Factory) kindArray(rnd *Random, T reflect.Type) any {
var (
rtype = reflect.TypeOf(T)
rarray = reflect.New(rtype).Elem()
rarray = reflect.New(T).Elem()
total = rnd.IntN(rarray.Len())
)
for i := 0; i < total; i++ {
v := f.Make(rnd, reflect.New(rtype.Elem()).Elem().Interface())
v := f.Make(rnd, reflect.New(T.Elem()).Elem().Interface())
rarray.Index(i).Set(reflect.ValueOf(v))
}
return rarray.Interface()
}

func (f *Factory) kindChan(rnd *Random, T any) any {
return reflect.MakeChan(reflect.TypeOf(T), 0).Interface()
func (f *Factory) kindChan(rnd *Random, T reflect.Type) any {
return reflect.MakeChan(T, 0).Interface()
}
Loading

0 comments on commit a0437ef

Please sign in to comment.