qmuntal / stateless

Go library for creating finite state machines
BSD 2-Clause "Simplified" License
898 stars 47 forks source link

SetTriggerParameters enhancment: validate interfaces #45

Closed delwaterman closed 2 years ago

delwaterman commented 2 years ago

Currently SetTriggerParameters only matches types exactly. It would be great if instead of requiring the exact type, you could pass SetTriggerParameters and validateParameters used reflect.Value#Implements to validate the parameter.

qmuntal commented 2 years ago

Could you share and code snippet example with what you want to achieve?

delwaterman commented 2 years ago

I have a few states where I want to pass an error through a transition

errIntType := reflect.TypeOf((*error)(nil)).Elem()
sm.SetTriggerParameters(ActionReturnError, errIntType)

sm.Configure(StateFinished).
        OnEntryFrom(ActionReturnError, func(ctx context.Context, args ...interface{}) error {
            err := args[0].(error)
            r := &VolunteerResult{
                Err: err,
            }

            chResult <- r
            close(chResult)

            return nil
        })
delwaterman commented 2 years ago

From the example of https://pkg.go.dev/reflect#TypeOf you can then actually check if a type implements an interace:

mport (
    "fmt"
    "io"
    "os"
    "reflect"
)

func main() {
    // As interface types are only used for static typing, a
    // common idiom to find the reflection Type for an interface
    // type Foo is to use a *Foo value.
    writerType := reflect.TypeOf((*io.Writer)(nil)).Elem()

    fileType := reflect.TypeOf((*os.File)(nil))
    fmt.Println(fileType.Implements(writerType))

}
qmuntal commented 2 years ago

Implemented in #46