gtsocial-umbx

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

util.go (1314B)


      1 package bun
      2 
      3 import "reflect"
      4 
      5 func indirect(v reflect.Value) reflect.Value {
      6 	switch v.Kind() {
      7 	case reflect.Interface:
      8 		return indirect(v.Elem())
      9 	case reflect.Ptr:
     10 		return v.Elem()
     11 	default:
     12 		return v
     13 	}
     14 }
     15 
     16 func walk(v reflect.Value, index []int, fn func(reflect.Value)) {
     17 	v = reflect.Indirect(v)
     18 	switch v.Kind() {
     19 	case reflect.Slice:
     20 		sliceLen := v.Len()
     21 		for i := 0; i < sliceLen; i++ {
     22 			visitField(v.Index(i), index, fn)
     23 		}
     24 	default:
     25 		visitField(v, index, fn)
     26 	}
     27 }
     28 
     29 func visitField(v reflect.Value, index []int, fn func(reflect.Value)) {
     30 	v = reflect.Indirect(v)
     31 	if len(index) > 0 {
     32 		v = v.Field(index[0])
     33 		if v.Kind() == reflect.Ptr && v.IsNil() {
     34 			return
     35 		}
     36 		walk(v, index[1:], fn)
     37 	} else {
     38 		fn(v)
     39 	}
     40 }
     41 
     42 func typeByIndex(t reflect.Type, index []int) reflect.Type {
     43 	for _, x := range index {
     44 		switch t.Kind() {
     45 		case reflect.Ptr:
     46 			t = t.Elem()
     47 		case reflect.Slice:
     48 			t = indirectType(t.Elem())
     49 		}
     50 		t = t.Field(x).Type
     51 	}
     52 	return indirectType(t)
     53 }
     54 
     55 func indirectType(t reflect.Type) reflect.Type {
     56 	if t.Kind() == reflect.Ptr {
     57 		t = t.Elem()
     58 	}
     59 	return t
     60 }
     61 
     62 func sliceElemType(v reflect.Value) reflect.Type {
     63 	elemType := v.Type().Elem()
     64 	if elemType.Kind() == reflect.Interface && v.Len() > 0 {
     65 		return indirect(v.Index(0).Elem()).Type()
     66 	}
     67 	return indirectType(elemType)
     68 }