From 0452a5f75e0644a0868b6b519c3b30b2fad93ecf Mon Sep 17 00:00:00 2001
From: Matt Bell <mappum@gmail.com>
Date: Wed, 17 Dec 2014 16:20:52 -0800
Subject: [PATCH] commands: Made default JSON marshaler support channel output

---
 commands/channelmarshaler.go | 34 ++++++++++++++++++++++++++++++++++
 commands/response.go         | 22 ++++++++++++++++------
 2 files changed, 50 insertions(+), 6 deletions(-)
 create mode 100644 commands/channelmarshaler.go

diff --git a/commands/channelmarshaler.go b/commands/channelmarshaler.go
new file mode 100644
index 000000000..826b32eab
--- /dev/null
+++ b/commands/channelmarshaler.go
@@ -0,0 +1,34 @@
+package commands
+
+import "io"
+
+type ChannelMarshaler struct {
+	Channel   <-chan interface{}
+	Marshaler func(interface{}) (io.Reader, error)
+
+	reader io.Reader
+}
+
+func (cr *ChannelMarshaler) Read(p []byte) (int, error) {
+	if cr.reader == nil {
+		val, more := <-cr.Channel
+		if !more {
+			return 0, io.EOF
+		}
+
+		r, err := cr.Marshaler(val)
+		if err != nil {
+			return 0, err
+		}
+		cr.reader = r
+	}
+
+	n, err := cr.reader.Read(p)
+	if err != nil && err != io.EOF {
+		return n, err
+	}
+	if n == 0 {
+		cr.reader = nil
+	}
+	return n, nil
+}
diff --git a/commands/response.go b/commands/response.go
index f776605b3..4dd717235 100644
--- a/commands/response.go
+++ b/commands/response.go
@@ -40,20 +40,30 @@ const (
 	// TODO: support more encoding types
 )
 
+func marshalJson(value interface{}) (io.Reader, error) {
+	b, err := json.MarshalIndent(value, "", "  ")
+	if err != nil {
+		return nil, err
+	}
+	return bytes.NewReader(b), nil
+}
+
 var marshallers = map[EncodingType]Marshaler{
 	JSON: func(res Response) (io.Reader, error) {
+		if ch, ok := res.Output().(chan interface{}); ok {
+			return &ChannelMarshaler{
+				Channel:   ch,
+				Marshaler: marshalJson,
+			}, nil
+		}
+
 		var value interface{}
 		if res.Error() != nil {
 			value = res.Error()
 		} else {
 			value = res.Output()
 		}
-
-		b, err := json.MarshalIndent(value, "", "  ")
-		if err != nil {
-			return nil, err
-		}
-		return bytes.NewReader(b), nil
+		return marshalJson(value)
 	},
 	XML: func(res Response) (io.Reader, error) {
 		var value interface{}
-- 
GitLab