From 0d497ca0df4d66f5e40b1bcac632c6e0b24c8603 Mon Sep 17 00:00:00 2001 From: Gorbunov Kirill Andreevich Date: Tue, 27 Feb 2024 21:05:42 +0300 Subject: [PATCH] #97 add As for Broker. --- broker/wrap.go | 34 +++++++++++++++++++ broker/wrap_test.go | 83 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 broker/wrap.go create mode 100644 broker/wrap_test.go diff --git a/broker/wrap.go b/broker/wrap.go new file mode 100644 index 00000000..331b1d63 --- /dev/null +++ b/broker/wrap.go @@ -0,0 +1,34 @@ +package broker + +import ( + "reflect" +) + +func As(b Broker, target any) bool { + if b == nil { + return false + } + if target == nil { + return false + } + val := reflect.ValueOf(target) + typ := val.Type() + if typ.Kind() != reflect.Ptr || val.IsNil() { + return false + } + targetType := typ.Elem() + if targetType.Kind() != reflect.Interface && !targetType.Implements(brokerType) { + return false + } + return as(b, val, targetType) +} + +func as(b Broker, targetVal reflect.Value, targetType reflect.Type) bool { + if reflect.TypeOf(b).AssignableTo(targetType) { + targetVal.Elem().Set(reflect.ValueOf(b)) + return true + } + return false +} + +var brokerType = reflect.TypeOf((*Broker)(nil)).Elem() diff --git a/broker/wrap_test.go b/broker/wrap_test.go new file mode 100644 index 00000000..671ea1b3 --- /dev/null +++ b/broker/wrap_test.go @@ -0,0 +1,83 @@ +package broker + +import ( + "context" + "fmt" + "reflect" + "testing" + + "go.unistack.org/micro/v4/options" +) + +type bro struct { + name string +} + +func (p *bro) Name() string { return p.name } +func (p *bro) Init(opts ...options.Option) error { return nil } + +// Options returns broker options +func (p *bro) Options() Options { return Options{} } + +// Address return configured address +func (p *bro) Address() string { return "" } + +// Connect connects to broker +func (p *bro) Connect(ctx context.Context) error { return nil } + +// Disconnect disconnect from broker +func (p *bro) Disconnect(ctx context.Context) error { return nil } + +// Publish message, msg can be single broker.Message or []broker.Message +func (p *bro) Publish(ctx context.Context, msg interface{}, opts ...options.Option) error { return nil } + +// Subscribe subscribes to topic message via handler +func (p *bro) Subscribe(ctx context.Context, topic string, handler interface{}, opts ...options.Option) (Subscriber, error) { + return nil, nil +} + +// String type of broker +func (p *bro) String() string { return p.name } + +func TestAs(t *testing.T) { + var b *bro + broTarget := &bro{name: "kafka"} + + testCases := []struct { + b Broker + target any + match bool + want any + }{ + { + broTarget, + &b, + true, + broTarget, + }, + { + nil, + &b, + false, + nil, + }, + } + for i, tc := range testCases { + name := fmt.Sprintf("%d:As(Errorf(..., %v), %v)", i, tc.b, tc.target) + // Clear the target pointer, in case it was set in a previous test. + rtarget := reflect.ValueOf(tc.target) + rtarget.Elem().Set(reflect.Zero(reflect.TypeOf(tc.target).Elem())) + t.Run(name, func(t *testing.T) { + match := As(tc.b, tc.target) + if match != tc.match { + t.Fatalf("match: got %v; want %v", match, tc.match) + } + if !match { + return + } + if got := rtarget.Elem().Interface(); got != tc.want { + t.Fatalf("got %#v, want %#v", got, tc.want) + } + }) + } +}