]> git repos ~mattia - go-utility.git/commitdiff
Reflect: Method Inspection v0.0.4
authorMattia Cabrini <dev@matiacabrini.com>
Sat, 8 Jul 2023 19:51:02 +0000 (21:51 +0200)
committerMattia Cabrini <dev@matiacabrini.com>
Sat, 8 Jul 2023 19:51:02 +0000 (21:51 +0200)
method.go [new file with mode: 0644]
reflect.go
reflect_test.go

diff --git a/method.go b/method.go
new file mode 100644 (file)
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()
+}
index 82300faa9e86a4d6a727d9f2980f88691e6aa3a7..8e7d215b5b304300c9657d9d402dda430bd3bcca 100644 (file)
@@ -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
index f95f6af6a554eb28234de10abacbcf07a04c90ab..e4a665934f26d6997eb3bb959d5deeea476a40c8 100644 (file)
@@ -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()