Skip to content

Commit

Permalink
Typed signatures for event handlers.
Browse files Browse the repository at this point in the history
Signed-off-by: Pavel Patrin <ppatrin@nvidia.com>
  • Loading branch information
pavelpatrin committed Aug 5, 2024
1 parent 0c7febf commit 2eb2532
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 4 deletions.
18 changes: 15 additions & 3 deletions events.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,28 @@ func (em *events) Trigger(event Event) error {
func (em *events) callTypedHandler(handler reflect.Value, args []any) error {
// Prepare slice of in arguments for handler.
handlerInArgs := make([]reflect.Value, 0, handler.Type().NumIn())
for index, eventArg := range args {
eventArgType := reflect.TypeOf(eventArg)

// Fill handler args with provided event args.
maxArgsLen := min(len(args), handler.Type().NumIn())

Check failure on line 95 in events.go

View workflow job for this annotation

GitHub Actions / build

undefined: min
for index := 0; index < maxArgsLen; index++ {
eventArgType := reflect.TypeOf(args[index])
eventArgValue := reflect.ValueOf(args[index])
handlerArgType := handler.Type().In(index)
if !eventArgType.AssignableTo(handlerArgType) {
return fmt.Errorf(
"%w: type '%s' is not assignable to '%s' (index %d)",
HandlerArgTypeMismatchError, eventArgType, handlerArgType, index,
)
}
handlerInArgs = append(handlerInArgs, reflect.ValueOf(eventArg))
handlerInArgs = append(handlerInArgs, eventArgValue)
}

// Fill handler args with default type values.
if len(handlerInArgs) < handler.Type().NumIn() {
for index := len(handlerInArgs); index < handler.Type().NumIn(); index++ {
zeroValuePtr := reflect.New(handler.Type().In(index))
handlerInArgs = append(handlerInArgs, zeroValuePtr.Elem())
}
}

// Invoke original event handler function.
Expand Down
14 changes: 14 additions & 0 deletions events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ func TestEvents(t *testing.T) {
testEvent1Args := [][]any(nil)
testEvent2Args := [][]any(nil)
testEvent3Args := [][]any(nil)
testEvent4Args := [][]any(nil)
testEvent5Args := [][]any(nil)

ev := &events{events: make(map[string][]handler)}
ev.Subscribe("TestEvent1", func(args ...any) {
Expand All @@ -23,14 +25,26 @@ func TestEvents(t *testing.T) {
testEvent3Args = append(testEvent3Args, []any{x, y, z})
return nil
})
ev.Subscribe("TestEvent4", func(x string, y int) error {
testEvent4Args = append(testEvent4Args, []any{x, y})
return nil
})
ev.Subscribe("TestEvent5", func(x string, y int, z bool) error {
testEvent5Args = append(testEvent5Args, []any{x, y, z})
return nil
})

equal(t, ev.Trigger(NewEvent("TestEvent1", 1)), nil)
equal(t, ev.Trigger(NewEvent("TestEvent1", "x")), nil)
equal(t, ev.Trigger(NewEvent("TestEvent2", true)), nil)
equal(t, ev.Trigger(NewEvent("TestEvent3", "x", 1, true)), nil)
equal(t, ev.Trigger(NewEvent("TestEvent4", "x", 1, true)), nil)
equal(t, ev.Trigger(NewEvent("TestEvent5", "x", 1)), nil)
equal(t, testEvent1Args, [][]any{{1}, {"x"}})
equal(t, testEvent2Args, [][]any{{true}})
equal(t, testEvent3Args, [][]any{{"x", 1, true}})
equal(t, testEvent4Args, [][]any{{"x", 1}})
equal(t, testEvent5Args, [][]any{{"x", 1, false}})
}

func equal(t *testing.T, a, b any) {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/NVIDIA/gontainer

go 1.20
go 1.21

0 comments on commit 2eb2532

Please sign in to comment.