@cryptotaxi247 / kubo / commits / 4af61ad99

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)