/
command.go
111 lines (96 loc) · 2.61 KB
/
command.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package cmd
import (
"github.com/robmcl4/mycroft/app"
"strings"
"errors"
"fmt"
"log"
)
type Command struct {
Execute func()
}
// Parse a command given the command blob (verb and body, no message length)
func ParseCommand(a *app.App, blob []byte) (*Command) {
ret, err := internalParseCommand(a, blob)
if err != nil {
log.Printf("General failure: %s\n", err.Error())
recieved := string(blob)
gf := NewGeneralFailure(a, recieved, err.Error())
ret = new(Command)
ret.Execute = gf.Execute
}
return ret
}
func internalParseCommand(a *app.App, blob []byte) (*Command, error) {
str := string(blob)
first_space := strings.Index(str, " ")
var verb string
var body []byte
if first_space < 0 {
verb = str
} else {
verb = str[:first_space]
if first_space == len(str)-1 {
return nil, errors.New("Cannot end verb with space")
}
body = []byte(str[first_space+1:])
}
switch verb {
case "APP_MANIFEST":
return NewAppManifest(a, body)
case "APP_UP":
return NewStatusChange(a, app.STATUS_UP, nil)
case "APP_DOWN":
return NewStatusChange(a, app.STATUS_DOWN, nil)
case "APP_IN_USE":
return NewStatusChange(a, app.STATUS_IN_USE, body)
case "MSG_QUERY":
return NewMsgQuery(a, body)
case "MSG_BROADCAST":
return NewMsgBroadcast(a, body)
case "MSG_QUERY_SUCCESS":
return NewMsgQuerySuccess(a, body)
case "MSG_QUERY_FAIL":
return NewMsgQueryFail(a, body)
}
return nil, fmt.Errorf("No matching verb found for %s", verb)
}
// get a string from the given map
func getString(m map[string]interface{}, key string) (string, bool) {
if val, ok := m[key]; ok {
switch vv := val.(type) {
case string:
return vv, true
default:
return "", false
}
} else {
return "", false
}
}
// get an integer from the given map
func getInt(m map[string]interface{}, key string) (int, bool) {
if val, ok := m[key]; ok {
switch vv := val.(type) {
case float64:
return int(vv), true
default:
return 0, false
}
} else {
return 0, false
}
}
// get a map from the given map
func getMap(m map[string]interface{}, key string) (map[string]interface{}, bool) {
if val, ok := m[key]; ok {
switch vv := val.(type) {
case map[string]interface{}:
return vv, true
default:
return nil, false
}
} else {
return nil, false
}
}