From 562b1ab9b7364fa967571293d884892d1168138a Mon Sep 17 00:00:00 2001
From: Vasiliy Tolstov <v.tolstov@unistack.org>
Date: Fri, 7 Mar 2025 15:26:20 +0300
Subject: [PATCH] broker: simplify handler check

Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
---
 broker/broker.go     |  2 +-
 broker/subscriber.go | 85 ++++----------------------------------------
 2 files changed, 7 insertions(+), 80 deletions(-)

diff --git a/broker/broker.go b/broker/broker.go
index 53b15d4e..3664433a 100644
--- a/broker/broker.go
+++ b/broker/broker.go
@@ -21,7 +21,7 @@ var (
 	// ErrInvalidMessage returns when invalid Message passed
 	ErrInvalidMessage = errors.New("invalid message")
 	// ErrInvalidHandler returns when subscriber passed to Subscribe
-	ErrInvalidHandler = errors.New("invalid handler")
+	ErrInvalidHandler = errors.New("invalid handler, ony func(Message) error and func([]Message) error supported")
 	// DefaultGracefulTimeout
 	DefaultGracefulTimeout = 5 * time.Second
 )
diff --git a/broker/subscriber.go b/broker/subscriber.go
index bdced69c..df6f58a8 100644
--- a/broker/subscriber.go
+++ b/broker/subscriber.go
@@ -1,87 +1,14 @@
 package broker
 
-import (
-	"fmt"
-	"reflect"
-	"unicode"
-	"unicode/utf8"
-)
-
-const (
-	messageSig  = "func(broker.Message) error"
-	messagesSig = "func([]broker.Message) error"
-)
-
-// Precompute the reflect type for error. Can't use error directly
-// because Typeof takes an empty interface value. This is annoying.
-var typeOfError = reflect.TypeOf((*error)(nil)).Elem()
-
-// Is this an exported - upper case - name?
-func isExported(name string) bool {
-	r, _ := utf8.DecodeRuneInString(name)
-	return unicode.IsUpper(r)
-}
-
-// Is this type exported or a builtin?
-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() == ""
-}
-
 // IsValidHandler func signature
 func IsValidHandler(sub interface{}) error {
-	typ := reflect.TypeOf(sub)
-	var argType reflect.Type
-	switch typ.Kind() {
-	case reflect.Func:
-		name := "Func"
-		switch typ.NumIn() {
-		case 1:
-			argType = typ.In(0)
-		default:
-			return fmt.Errorf("subscriber %v takes wrong number of args: %v required signature %s", name, typ.NumIn(), messageSig)
-		}
-		if !isExportedOrBuiltinType(argType) {
-			return fmt.Errorf("subscriber %v argument type not exported: %v", name, argType)
-		}
-		if typ.NumOut() != 1 {
-			return fmt.Errorf("subscriber %v has wrong number of return values: %v require signature %s",
-				name, typ.NumOut(), messageSig)
-		}
-		if returnType := typ.Out(0); returnType != typeOfError {
-			return fmt.Errorf("subscriber %v returns %v not error", name, returnType.String())
-		}
+	switch sub.(type) {
 	default:
-		hdlr := reflect.ValueOf(sub)
-		name := reflect.Indirect(hdlr).Type().Name()
-
-		for m := 0; m < typ.NumMethod(); m++ {
-			method := typ.Method(m)
-			switch method.Type.NumIn() {
-			case 3:
-				argType = method.Type.In(2)
-			default:
-				return fmt.Errorf("subscriber %v.%v takes wrong number of args: %v required signature %s",
-					name, method.Name, method.Type.NumIn(), messageSig)
-			}
-
-			if !isExportedOrBuiltinType(argType) {
-				return fmt.Errorf("%v argument type not exported: %v", name, argType)
-			}
-			if method.Type.NumOut() != 1 {
-				return fmt.Errorf(
-					"subscriber %v.%v has wrong number of return values: %v require signature %s",
-					name, method.Name, method.Type.NumOut(), messageSig)
-			}
-			if returnType := method.Type.Out(0); returnType != typeOfError {
-				return fmt.Errorf("subscriber %v.%v returns %v not error", name, method.Name, returnType.String())
-			}
-		}
+		return ErrInvalidHandler
+	case func(Message) error:
+		break
+	case func([]Message) error:
+		break
 	}
-
 	return nil
 }