-
Notifications
You must be signed in to change notification settings - Fork 191
/
gofunc.go
113 lines (97 loc) · 2.4 KB
/
gofunc.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package goinfo
import (
"reflect"
"runtime"
"strings"
"unicode"
"github.com/gookit/goutil/strutil"
)
// FullFcName struct.
type FullFcName struct {
// FullName eg: "github.com/gookit/goutil/goinfo.PanicIf"
FullName string
pkgPath string // "github.com/gookit/goutil/goinfo"
pkgName string // "goinfo"
funcName string // "PanicIf"
}
// Parse the full func name.
func (ffn *FullFcName) Parse() {
if ffn.funcName != "" {
return
}
i := strings.LastIndex(ffn.FullName, "/")
ffn.pkgPath = ffn.FullName[:i+1]
// spilt get pkg and func name
ffn.pkgName, ffn.funcName = strutil.MustCut(ffn.FullName[i+1:], ".")
ffn.pkgPath += ffn.pkgName
}
// PkgPath string get. eg: github.com/gookit/goutil/goinfo
func (ffn *FullFcName) PkgPath() string {
ffn.Parse()
return ffn.pkgPath
}
// PkgName string get. eg: goinfo
func (ffn *FullFcName) PkgName() string {
ffn.Parse()
return ffn.pkgName
}
// FuncName get short func name. eg: PanicIf
func (ffn *FullFcName) FuncName() string {
ffn.Parse()
return ffn.funcName
}
// String get full func name string, pkg path and func name.
func (ffn *FullFcName) String() string {
return ffn.FullName
}
// FuncName get full func name, contains pkg path.
//
// eg:
//
// // OUTPUT: github.com/gookit/goutil/goinfo.PkgName
// goinfo.FuncName(goinfo.PkgName)
func FuncName(fn any) string {
return runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
}
// CutFuncName get pkg path and short func name
// eg:
//
// "github.com/gookit/goutil/goinfo.FuncName" => [github.com/gookit/goutil/goinfo, FuncName]
func CutFuncName(fullFcName string) (pkgPath, shortFnName string) {
ffn := FullFcName{FullName: fullFcName}
return ffn.PkgPath(), ffn.FuncName()
}
// PkgName get current package name
//
// Usage:
//
// fullFcName := goinfo.FuncName(fn)
// pgkName := goinfo.PkgName(fullFcName)
func PkgName(fullFcName string) string {
for {
lastPeriod := strings.LastIndex(fullFcName, ".")
lastSlash := strings.LastIndex(fullFcName, "/")
if lastPeriod > lastSlash {
fullFcName = fullFcName[:lastPeriod]
} else {
break
}
}
return fullFcName
}
// GoodFuncName reports whether the function name is a valid identifier.
func GoodFuncName(name string) bool {
if name == "" {
return false
}
for i, r := range name {
switch {
case r == '_':
case i == 0 && !unicode.IsLetter(r):
return false
case !unicode.IsLetter(r) && !unicode.IsDigit(r):
return false
}
}
return true
}