From: Mattia Cabrini Date: Sat, 8 Jul 2023 19:51:02 +0000 (+0200) Subject: Reflect: Method Inspection X-Git-Tag: v0.0.4 X-Git-Url: https://git.theboydaily.dev/mattia?a=commitdiff_plain;h=a14bbfac29c514521c7026f130d058e14845b8d7;p=go-utility.git Reflect: Method Inspection --- diff --git a/method.go b/method.go new file mode 100644 index 0000000..4912da8 --- /dev/null +++ b/method.go @@ -0,0 +1,54 @@ +/* +MIT License + +Copyright (c) 2023 Mattia Cabrini + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package utility + +import ( + "reflect" +) + +type Method struct { + to reflect.Method + numIn int + + F GenericFunc +} + +func newMethod(to reflect.Method, callable GenericFunc) (m *Method) { + m = &Method{ + to: to, + numIn: to.Type.NumIn() - 1, + F: callable, + } + + return +} + +func (m *Method) NumIn() int { + return m.numIn +} + +func (m *Method) ParamKind(i int) reflect.Kind { + return m.to.Type.In(i + 1).Kind() +} diff --git a/reflect.go b/reflect.go index 82300fa..8e7d215 100644 --- a/reflect.go +++ b/reflect.go @@ -31,13 +31,13 @@ import ( type GenericFunc func(...interface{}) ([]interface{}, error) -func checkMethodArgs(methodVO reflect.Method, args []reflect.Value) error { - if m, a := methodVO.Type.NumIn(), len(args); m != a+1 { +func checkMethodArgs(methodTO reflect.Method, args []reflect.Value) error { + if m, a := methodTO.Type.NumIn(), len(args); m != a+1 { return fmt.Errorf("expected %d arguments, got %d", m, a) } for i, arg := range args { - argTypeExpected := methodVO.Type.In(i + 1) + argTypeExpected := methodTO.Type.In(i + 1) if i == 0 { continue // skip the object itself @@ -73,7 +73,7 @@ func newGenericFunc(obj interface{}, methodTO reflect.Method, methodVO reflect.V } } -func GetMethod(obj interface{}, name string, suffix string) GenericFunc { +func GetMethod(obj interface{}, name string, suffix string) *Method { to := reflect.TypeOf(obj) vo := reflect.ValueOf(obj) @@ -81,8 +81,8 @@ func GetMethod(obj interface{}, name string, suffix string) GenericFunc { if b { methodVO := vo.MethodByName(name + suffix) - - return newGenericFunc(obj, methodTO, methodVO) + callable := newGenericFunc(obj, methodTO, methodVO) + return newMethod(methodTO, callable) } return nil diff --git a/reflect_test.go b/reflect_test.go index f95f6af..e4a6659 100644 --- a/reflect_test.go +++ b/reflect_test.go @@ -24,7 +24,10 @@ SOFTWARE. package utility -import "testing" +import ( + "reflect" + "testing" +) type testType struct { A int `con:"true" con2:"true"` @@ -46,14 +49,14 @@ func (t *testType) GetABstruct(a int, b testType) (int, int) { func TestMethodOk0(t *testing.T) { obj := testType{0, 1} - f := GetMethod(&obj, "GetAB", "") + m := GetMethod(&obj, "GetAB", "") - if f == nil { + if m == nil { t.Fail() return } - results, err := f(0, 1) + results, err := m.F(0, 1) if err != nil { t.Error(err) @@ -66,19 +69,29 @@ func TestMethodOk0(t *testing.T) { if results[1].(int) != 2 { t.Error(1) } + + if m.ParamKind(0) != reflect.Int { + t.Error(2) + } + if m.ParamKind(1) != reflect.Int { + t.Error(3) + } + if m.NumIn() != 2 { + t.Error(4) + } } func TestMethodOk1(t *testing.T) { obj := testType{0, 1} - f := GetMethod(&obj, "GetAB", "interface") + m := GetMethod(&obj, "GetAB", "interface") - if f == nil { + if m == nil { t.Fail() return } - results, err := f(0, 1) + results, err := m.F(0, 1) if err != nil { t.Error(err) @@ -96,14 +109,14 @@ func TestMethodOk1(t *testing.T) { func TestMethodOk2(t *testing.T) { obj := testType{0, 1} - f := GetMethod(&obj, "GetAB", "struct") + m := GetMethod(&obj, "GetAB", "struct") - if f == nil { + if m == nil { t.Fail() return } - results, err := f(0, obj) + results, err := m.F(0, obj) if err != nil { t.Error(err) @@ -121,14 +134,14 @@ func TestMethodOk2(t *testing.T) { func TestMethodArgCountKo(t *testing.T) { obj := testType{0, 1} - f := GetMethod(&obj, "Get", "AB") + m := GetMethod(&obj, "Get", "AB") - if f == nil { + if m == nil { t.Fail() return } - _, err := f(0) + _, err := m.F(0) if err == nil { t.Fail() @@ -138,14 +151,14 @@ func TestMethodArgCountKo(t *testing.T) { func TestMethodArgTypeKo(t *testing.T) { obj := testType{0, 1} - f := GetMethod(&obj, "Get", "AB") + m := GetMethod(&obj, "Get", "AB") - if f == nil { + if m == nil { t.Fail() return } - _, err := f(0, "1") + _, err := m.F(0, "1") if err == nil { t.Fail()