You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nnet/component/util.go

64 lines
1.4 KiB
Go

package component
import (
"reflect"
"unicode"
"unicode/utf8"
)
var (
typeOfError = reflect.TypeOf((*error)(nil)).Elem()
typeOfBytes = reflect.TypeOf(([]byte)(nil))
// TODO cycle not allow IConnection
typeOfConnection = reflect.TypeOf(([]byte)(nil))
)
func isExported(name string) bool {
w, _ := utf8.DecodeRuneInString(name)
return unicode.IsUpper(w)
}
func isExportedOrBuiltinType(t reflect.Type) bool {
for t.Kind() == reflect.Ptr {
t = t.Elem()
}
// PkgPath will be non-empty even for an exported type,
// so we need to check the type name as well.
return isExported(t.Name()) || t.PkgPath() == ""
}
func isHandlerMethod(method reflect.Method) bool {
mt := method.Type
// 必须是可导出的
if isExportedOrBuiltinType(mt) {
return false
}
// 必须具有3个入参: receiver, *Request, []byte/pointer
// receiver指代 func (*receiver) xxx() 的receiver部分
if mt.NumIn() != 3 {
return false
}
// 至少要有一个出参 且是error
if mt.NumOut() < 1 {
return false
}
// 第一个显式入参必须是实现了IConnection的具体类的指针类型
if t1 := mt.In(1); t1.Kind() != reflect.Ptr || t1 != typeOfConnection {
return false
}
// 第二个显式入参必须是 []byte 或者 任意pointer
if t2 := mt.In(2); t2.Kind() != reflect.Ptr || t2 != typeOfBytes {
return false
}
// 最后一个出参必须是error
if o1 := mt.Out(mt.NumOut() - 1); o1 != typeOfError {
return false
}
return true
}