Skip to content

Commit

Permalink
feat: refactor reflections utilities as per v3
Browse files Browse the repository at this point in the history
  • Loading branch information
sranka committed Nov 28, 2023
1 parent c1da0c5 commit 060d69e
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 16 deletions.
16 changes: 0 additions & 16 deletions api/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,22 +289,6 @@ func checkParamsType(p interface{}) error {
return nil
}

// getFieldType extracts type of value
func getFieldType(v reflect.Value) reflect.Type {
t := v.Type()
if t.Kind() == reflect.Ptr {
t = t.Elem()
v = v.Elem()
}
if t.Kind() == reflect.Interface && !v.IsNil() {
t = reflect.ValueOf(v.Interface()).Type()
}
return t
}

// timeType is the exact type for the Time
var timeType = reflect.TypeOf(time.Time{})

// validParamType validates that t is primitive type or string or interface
func validParamType(t reflect.Type) bool {
return (t.Kind() > reflect.Invalid && t.Kind() < reflect.Complex64) ||
Expand Down
72 changes: 72 additions & 0 deletions api/reflection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package api

import (
"fmt"
"reflect"
"time"
)

// checkContainerType validates the value is struct with simple type fields
// or a map with key as string and value as a simple type
func checkContainerType(p interface{}, alsoMap bool, usage string) error {
if p == nil {
return nil
}
t := reflect.TypeOf(p)
v := reflect.ValueOf(p)
if t.Kind() == reflect.Ptr {
t = t.Elem()
v = v.Elem()
}
if t.Kind() != reflect.Struct && (!alsoMap || t.Kind() != reflect.Map) {
return fmt.Errorf("cannot use %v as %s", t, usage)
}
switch t.Kind() {
case reflect.Struct:
fields := reflect.VisibleFields(t)
for _, f := range fields {
fv := v.FieldByIndex(f.Index)
t := getFieldType(fv)
if !validFieldType(t) {
return fmt.Errorf("cannot use field '%s' of type '%v' as a %s", f.Name, t, usage)
}

}
case reflect.Map:
key := t.Key()
if key.Kind() != reflect.String {
return fmt.Errorf("cannot use map key of type '%v' for %s name", key, usage)
}
for _, k := range v.MapKeys() {
f := v.MapIndex(k)
t := getFieldType(f)
if !validFieldType(t) {
return fmt.Errorf("cannot use map value type '%v' as a %s", t, usage)
}
}
}
return nil
}

// getFieldType extracts type of value
func getFieldType(v reflect.Value) reflect.Type {
t := v.Type()
if t.Kind() == reflect.Ptr {
t = t.Elem()
v = v.Elem()
}
if t.Kind() == reflect.Interface && !v.IsNil() {
t = reflect.ValueOf(v.Interface()).Type()
}
return t
}

// timeType is the exact type for the Time
var timeType = reflect.TypeOf(time.Time{})

// validFieldType validates that t is primitive type or string or interface
func validFieldType(t reflect.Type) bool {
return (t.Kind() > reflect.Invalid && t.Kind() < reflect.Complex64) ||
t.Kind() == reflect.String ||
t == timeType
}

0 comments on commit 060d69e

Please sign in to comment.