/ command.go
command.go
1 package dispatch2 2 3 import ( 4 "context" 5 "fmt" 6 ) 7 8 type Command[Config any] interface { 9 After(middlewares ...MiddlewareFunc[Config]) 10 Aliases() []string 11 Before(middlewares ...MiddlewareFunc[Config]) 12 Execute(context.Context, *Config, []string) error 13 Executer() Executer[Config] 14 NSubcommands() int 15 Name() string 16 Register(name, synopsis, usage string, aliases []string, executer Executer[Config]) error 17 RegisterCommand(Command[Config]) error 18 RegisterFunc(name, synopsis, usage string, aliases []string, executer ExecuterFunc[Config]) error 19 Subcommands() []Command[Config] 20 Synopsis() string 21 Usage() string 22 } 23 24 type command[Config any] struct { 25 afterMiddlewares []MiddlewareFunc[Config] 26 aliases []string 27 beforeMiddlewares []MiddlewareFunc[Config] 28 executer Executer[Config] 29 name string 30 subcommands []Command[Config] 31 synopsis string 32 usage string 33 } 34 35 var _ Command[struct{}] = &command[struct{}]{} 36 37 func NewCommand[Config any](name, synopsis, usage string, aliases []string, executer Executer[Config]) *command[Config] { 38 return &command[Config]{ 39 aliases: aliases, 40 executer: executer, 41 name: name, 42 synopsis: synopsis, 43 usage: usage, 44 } 45 } 46 47 func NewCommandFunc[Config any](name, synopsis, usage string, aliases []string, executer ExecuterFunc[Config]) *command[Config] { 48 return &command[Config]{ 49 aliases: aliases, 50 executer: executer, 51 name: name, 52 synopsis: synopsis, 53 usage: usage, 54 } 55 } 56 func (c *command[Config]) After(middlewares ...MiddlewareFunc[Config]) { 57 for _, m := range middlewares { 58 c.afterMiddlewares = append(c.afterMiddlewares, invertMiddleware(m)) 59 } 60 } 61 62 func (c *command[Config]) Before(middlewares ...MiddlewareFunc[Config]) { 63 c.beforeMiddlewares = append(c.beforeMiddlewares, middlewares...) 64 } 65 66 func (c *command[Config]) Subcommands() []Command[Config] { 67 return c.subcommands 68 } 69 70 func (c *command[Config]) NSubcommands() int { 71 return len(c.subcommands) 72 } 73 74 func (c *command[Config]) Aliases() []string { 75 return c.aliases 76 } 77 78 func (c *command[Config]) Executer() Executer[Config] { 79 return c.executer 80 } 81 82 func (c *command[Config]) Name() string { 83 return c.name 84 } 85 func (c *command[Config]) Synopsis() string { 86 return c.synopsis 87 } 88 func (c *command[Config]) Usage() string { 89 return c.usage 90 } 91 92 func (c *command[Config]) RegisterCommand(command Command[Config]) error { 93 c.subcommands = append(c.subcommands, command) 94 //TODO check if name or alias is taken 95 return nil 96 } 97 98 func (c *command[Config]) Register(name, synopsis, usage string, aliases []string, executer Executer[Config]) error { 99 return c.RegisterCommand(NewCommand(name, synopsis, usage, aliases, executer)) 100 } 101 102 func (c *command[Config]) RegisterFunc(name, synopsis, usage string, aliases []string, executerFunc ExecuterFunc[Config]) error { 103 return c.RegisterCommand(NewCommand(name, synopsis, usage, aliases, executerFunc)) 104 } 105 106 func (c *command[Config]) Execute(ctx context.Context, cfg *Config, args []string) error { 107 select { 108 case <-ctx.Done(): 109 return ctx.Err() 110 default: 111 executer := c.Executer() 112 if executer == nil { 113 return fmt.Errorf("command: cannot execute nil executer") 114 } 115 116 // Apply AFTER middlewares (registration order, inverted) 117 for _, middleware := range c.afterMiddlewares { 118 executer = middleware(WrapExecuter(executer)) 119 } 120 121 // Before middlewares: (reverse order) 122 for i := len(c.beforeMiddlewares) - 1; i >= 0; i-- { 123 executer = c.beforeMiddlewares[i](WrapExecuter(executer)) 124 } 125 126 return executer.Execute(ctx, cfg, args) 127 } 128 }