commands: Added Command#Resolve
Matt Bell committed
Oct 15, 2014 at 17:08 UTC
4af61ad9944523886cded2ff0e09919448fdc025
1 file changed
+42
-14
commands/command.go
+42
-14
@@ -3,6 +3,7 @@ package commands
3
import (
4
"fmt"
5
"strings"
6
+ "errors"
7
)
8
9
type Command struct {
@@ -12,6 +13,8 @@ type Command struct {
13
subcommands map[string]*Command
14
}
15
16
+var NotCallableError = errors.New("This command can't be called directly. Try one of its subcommands.")
17
+
18
// Register adds a subcommand
19
func (c *Command) Register(id string, sub *Command) error {
20
if c.subcommands == nil {
@@ -37,10 +40,21 @@ func (c *Command) Register(id string, sub *Command) error {
40
41
// Call invokes the command at the given subcommand path
42
func (c *Command) Call(req *Request) *Response {
40
- cmd := c
43
res := &Response{req: req}
44
43
- options, err := cmd.GetOptions(req.path)
45
+ cmds, err := c.Resolve(req.path)
46
+ if err != nil {
47
+ res.SetError(err, Client)
48
+ return res
49
+ }
50
+ cmd := cmds[len(cmds)-1]
51
+
52
+ if(cmd.f == nil) {
53
+ res.SetError(NotCallableError, Client)
54
+ return res
55
+ }
56
+
57
+ options, err := c.GetOptions(req.path)
58
if err != nil {
59
res.SetError(err, Client)
60
return res
@@ -57,24 +71,38 @@ func (c *Command) Call(req *Request) *Response {
71
return res
72
}
73
74
+// Resolve gets the subcommands at the given path
75
+func (c *Command) Resolve(path []string) ([]*Command, error) {
76
+ cmds := make([]*Command, len(path) + 1)
77
+ cmds[0] = c
78
+
79
+ cmd := c
80
+ for i, name := range path {
81
+ cmd = cmd.Sub(name)
82
+
83
+ if cmd == nil {
84
+ pathS := strings.Join(path[0:i], "/")
85
+ return nil, fmt.Errorf("Undefined command: '%s'", pathS)
86
+ }
87
+
88
+ cmds[i+1] = cmd
89
+ }
90
+
91
+ return cmds, nil
92
+}
93
+
94
// GetOptions gets the options in the given path of commands
95
func (c *Command) GetOptions(path []string) (map[string]Option, error) {
96
options := make([]Option, len(c.Options))
97
copy(options, c.Options)
98
options = append(options, globalOptions...)
99
66
- // a nil path means this command, not a subcommand (same as an empty path)
67
- if path != nil {
68
- for i, id := range path {
69
- cmd := c.Sub(id)
70
-
71
- if cmd == nil {
72
- pathS := strings.Join(path[0:i], "/")
73
- return nil, fmt.Errorf("Undefined command: '%s'", pathS)
74
- }
75
-
76
- options = append(options, cmd.Options...)
77
- }
100
+ cmds, err := c.Resolve(path)
101
+ if err != nil {
102
+ return nil, err
103
+ }
104
+ for _, cmd := range cmds {
105
+ options = append(options, cmd.Options...)
106
}
107
108
optionsMap := make(map[string]Option)