Skip to content

Commit

Permalink
✨ feat: reflects - add new util func IsSimpleKind(), SetRValue()
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed May 25, 2023
1 parent d1fb1c8 commit 3849a6d
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 6 deletions.
10 changes: 9 additions & 1 deletion reflects/check.go
Expand Up @@ -5,7 +5,7 @@ import (
"reflect"
)

// HasChild check. eg: array, slice, map, struct
// HasChild type check. eg: array, slice, map, struct
func HasChild(v reflect.Value) bool {
switch v.Kind() {
case reflect.Array, reflect.Slice, reflect.Map, reflect.Struct:
Expand All @@ -19,6 +19,14 @@ func IsArrayOrSlice(k reflect.Kind) bool {
return k == reflect.Slice || k == reflect.Array
}

// IsSimpleKind kind in: string, bool, intX, uintX, floatX
func IsSimpleKind(k reflect.Kind) bool {
if reflect.String == k {
return true
}
return k > reflect.Invalid && k <= reflect.Float64
}

// IsAnyInt check is intX or uintX type
func IsAnyInt(k reflect.Kind) bool {
return k >= reflect.Int && k <= reflect.Uintptr
Expand Down
21 changes: 21 additions & 0 deletions reflects/check_test.go
Expand Up @@ -67,3 +67,24 @@ func TestIsEmptyValue(t *testing.T) {
rv := reflect.ValueOf(T{}).Field(0)
is.True(reflects.IsEmptyValue(rv))
}

func TestIsSimpleKind(t *testing.T) {
testCases := []struct {
name string
input reflect.Kind
expected bool
}{
{"invalid kind", reflect.Invalid, false},
{"string kind", reflect.String, true},
{"float64 kind", reflect.Float64, true},
{"bool kind", reflect.Bool, true},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if reflects.IsSimpleKind(tc.input) != tc.expected {
t.Errorf("expected %v but got %v", tc.expected, !tc.expected)
}
})
}
}
6 changes: 5 additions & 1 deletion reflects/conv.go
Expand Up @@ -130,7 +130,11 @@ func ValueByKind(val any, kind reflect.Kind) (rv reflect.Value, err error) {
return
}

// ConvSlice make new type slice from old slice
// ConvSlice make new type slice from old slice, will auto convert element type.
//
// TIPs:
//
// Only support kind: string, bool, intX, uintX, floatX
func ConvSlice(oldSlRv reflect.Value, newElemTyp reflect.Type) (rv reflect.Value, err error) {
if !IsArrayOrSlice(oldSlRv.Kind()) {
panic("only allow array or slice type value")
Expand Down
26 changes: 22 additions & 4 deletions reflects/util.go
Expand Up @@ -50,12 +50,17 @@ func Len(v reflect.Value) int {
return -1
}

// SliceSubKind get sub-elem kind of the array, slice, variadic-var.
// SliceSubKind get sub-elem kind of the array, slice, variadic-var. alias SliceElemKind()
func SliceSubKind(typ reflect.Type) reflect.Kind {
return SliceElemKind(typ)
}

// SliceElemKind get sub-elem kind of the array, slice, variadic-var.
//
// Usage:
//
// SliceSubKind(reflect.TypeOf([]string{"abc"})) // reflect.String
func SliceSubKind(typ reflect.Type) reflect.Kind {
// SliceElemKind(reflect.TypeOf([]string{"abc"})) // reflect.String
func SliceElemKind(typ reflect.Type) reflect.Kind {
if typ.Kind() == reflect.Slice || typ.Kind() == reflect.Array {
return typ.Elem().Kind()
}
Expand Down Expand Up @@ -91,7 +96,7 @@ func SetUnexportedValue(rv reflect.Value, value any) {
reflect.NewAt(rv.Type(), unsafe.Pointer(rv.UnsafeAddr())).Elem().Set(reflect.ValueOf(value))
}

// SetValue to a reflect.Value
// SetValue to a `reflect.Value`. will auto convert type if needed.
func SetValue(rv reflect.Value, val any) error {
// get real type of the ptr value
if rv.Kind() == reflect.Ptr {
Expand All @@ -112,6 +117,19 @@ func SetValue(rv reflect.Value, val any) error {
return err
}

// SetRValue to a `reflect.Value`. will direct set value without convert type.
func SetRValue(rv, val reflect.Value) {
if rv.Kind() == reflect.Ptr {
if rv.IsNil() {
elemTyp := rv.Type().Elem()
rv.Set(reflect.New(elemTyp))
}
rv = reflect.Indirect(rv)
}

rv.Set(val)
}

// EachMap process any map data
func EachMap(mp reflect.Value, fn func(key, val reflect.Value)) {
if fn == nil {
Expand Down
5 changes: 5 additions & 0 deletions reflects/util_test.go
Expand Up @@ -179,6 +179,11 @@ func TestSetValue(t *testing.T) {
rv := reflect.ValueOf("val")
_ = reflects.SetValue(rv, "new val")
})

// test for SetRValue()
rv = reflect.ValueOf(&iVal)
reflects.SetRValue(rv, reflect.ValueOf(456))
assert.Eq(t, 456, iVal)
}

func TestSetValue_map(t *testing.T) {
Expand Down

0 comments on commit 3849a6d

Please sign in to comment.