-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtypes.go
67 lines (59 loc) · 1.5 KB
/
types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package name
import (
"reflect"
"runtime"
"strings"
"github.com/cockroachdb/errors"
"go.stevenxie.me/gopkg/zero"
)
// OfType returns the type name of a value.
func OfType(v zero.Interface) string {
t := getElem(v)
if t.Kind() == reflect.Func {
return OfFunc(v)
}
return t.String()
}
// OfTypeFull returns the full type name of a value, including its import path.
func OfTypeFull(v zero.Interface) string {
t := getElem(v)
if t.Kind() == reflect.Func {
return OfFuncFull(v)
}
return t.PkgPath() + "." + t.Name()
}
// OfFunc returns the name of a function.
func OfFunc(v zero.Interface) string {
name := OfFuncFull(v)
tailIndex := strings.LastIndexByte(name, '/')
if tailIndex == -1 {
return name
}
return name[tailIndex+1:]
}
// OfFuncFull returns the full name of a function, within the context of its
// import path.
func OfFuncFull(v zero.Interface) string {
if k := reflect.TypeOf(v).Kind(); k != reflect.Func {
panic(errors.Newf("name: non-function type '%s'", k.String()))
}
f := runtime.FuncForPC(reflect.ValueOf(v).Pointer())
return f.Name()
}
// OfMethod returns the name of a method on a struct or interface.
func OfMethod(v zero.Interface) string {
name := OfFunc(v)
tailIndex := strings.LastIndexByte(name, '.')
if tailIndex == -1 {
panic(errors.New("name: func name has no character '.'"))
}
return name[tailIndex+1:]
}
func getElem(v zero.Interface) reflect.Type {
t := reflect.TypeOf(v)
switch t.Kind() {
case reflect.Ptr, reflect.Interface:
t = t.Elem()
}
return t
}