-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdispatch.go
More file actions
111 lines (100 loc) · 2.54 KB
/
Copy pathdispatch.go
File metadata and controls
111 lines (100 loc) · 2.54 KB
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 main
import (
"encoding/json"
"fmt"
)
// Request is the wire-level request envelope shared by HTTP and Bluetooth transports.
// Bluetooth uses a single newline-delimited JSON stream where each line carries a Request.
// HTTP wraps these per-route — the dispatcher accepts the same shape from either path.
type Request struct {
ID int `json:"id,omitempty"`
Type string `json:"type"`
Serial string `json:"serial,omitempty"`
Key string `json:"key,omitempty"`
Text string `json:"text,omitempty"`
Display *int `json:"display,omitempty"`
}
type Response struct {
ID int `json:"id,omitempty"`
OK bool `json:"ok"`
Data interface{} `json:"data,omitempty"`
Error string `json:"error,omitempty"`
}
// Dispatch executes a single Request and returns its Response. It never returns an error
// directly — failures are encoded in resp.OK / resp.Error so transports can serialize uniformly.
func Dispatch(req Request) Response {
resp := Response{ID: req.ID}
switch req.Type {
case "listDevices":
devices, err := ListDevices()
if err != nil {
resp.Error = err.Error()
return resp
}
if devices == nil {
devices = []Device{}
}
resp.OK = true
resp.Data = devices
case "listDisplays":
if req.Serial == "" {
resp.Error = "missing serial"
return resp
}
displays, err := ListDisplays(req.Serial)
if err != nil {
resp.Error = err.Error()
return resp
}
if displays == nil {
displays = []Display{}
}
resp.OK = true
resp.Data = displays
case "keyevent":
if req.Serial == "" {
resp.Error = "missing serial"
return resp
}
code, ok := keyMap[req.Key]
if !ok {
resp.Error = "unknown key: " + req.Key
return resp
}
displayID := -1
if req.Display != nil {
displayID = *req.Display
}
if err := SendKeyEvent(req.Serial, code, displayID); err != nil {
resp.Error = err.Error()
return resp
}
resp.OK = true
case "text":
if req.Serial == "" {
resp.Error = "missing serial"
return resp
}
if req.Text == "" {
resp.OK = true
return resp
}
displayID := -1
if req.Display != nil {
displayID = *req.Display
}
if err := SendText(req.Serial, req.Text, displayID); err != nil {
resp.Error = err.Error()
return resp
}
resp.OK = true
default:
resp.Error = fmt.Sprintf("unknown type: %q", req.Type)
}
return resp
}
// MarshalResponse is a tiny helper used by the Bluetooth handler so it doesn't need to
// import encoding/json directly.
func MarshalResponse(r Response) ([]byte, error) {
return json.Marshal(r)
}