commands: Made default JSON marshaler support channel output
Matt Bell committed
Dec 17, 2014 at 16:20 UTC
0452a5f75e0644a0868b6b519c3b30b2fad93ecf
2 files changed
+50
-6
commands/channelmarshaler.go
new
+34
@@ -0,0 +1,34 @@
1
+package commands
2
+
3
+import "io"
4
+
5
+type ChannelMarshaler struct {
6
+ Channel <-chan interface{}
7
+ Marshaler func(interface{}) (io.Reader, error)
8
+
9
+ reader io.Reader
10
+}
11
+
12
+func (cr *ChannelMarshaler) Read(p []byte) (int, error) {
13
+ if cr.reader == nil {
14
+ val, more := <-cr.Channel
15
+ if !more {
16
+ return 0, io.EOF
17
+ }
18
+
19
+ r, err := cr.Marshaler(val)
20
+ if err != nil {
21
+ return 0, err
22
+ }
23
+ cr.reader = r
24
+ }
25
+
26
+ n, err := cr.reader.Read(p)
27
+ if err != nil && err != io.EOF {
28
+ return n, err
29
+ }
30
+ if n == 0 {
31
+ cr.reader = nil
32
+ }
33
+ return n, nil
34
+}
commands/response.go
+16
-6
@@ -40,20 +40,30 @@ const (
40
// TODO: support more encoding types
41
)
42
43
+func marshalJson(value interface{}) (io.Reader, error) {
44
+ b, err := json.MarshalIndent(value, "", " ")
45
+ if err != nil {
46
+ return nil, err
47
+ }
48
+ return bytes.NewReader(b), nil
49
+}
50
+
51
var marshallers = map[EncodingType]Marshaler{
52
JSON: func(res Response) (io.Reader, error) {
53
+ if ch, ok := res.Output().(chan interface{}); ok {
54
+ return &ChannelMarshaler{
55
+ Channel: ch,
56
+ Marshaler: marshalJson,
57
+ }, nil
58
+ }
59
+
60
var value interface{}
61
if res.Error() != nil {
62
value = res.Error()
63
} else {
64
value = res.Output()
65
}
51
-
52
- b, err := json.MarshalIndent(value, "", " ")
53
- if err != nil {
54
- return nil, err
55
- }
56
- return bytes.NewReader(b), nil
66
+ return marshalJson(value)
67
},
68
XML: func(res Response) (io.Reader, error) {
69
var value interface{}