-
Notifications
You must be signed in to change notification settings - Fork 51
/
json_framing.go
49 lines (40 loc) · 1.37 KB
/
json_framing.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
package message
import (
"bufio"
"encoding/json"
"go.gazette.dev/core/labels"
)
type jsonFraming struct{}
// JSONMarshalerTo should be implemented (along with json.Unmarshaler)
// by the message being Marshaled if it needs to specify its JSON encoding method.
// If this interface is not implemented jsonFraming will default to encoding/json
// returns the number of bytes written and any error that occurs
type JSONMarshalerTo interface {
MarshalJSONTo(*bufio.Writer) (int, error)
}
// ContentType returns labels.ContentType_JSONLines.
func (*jsonFraming) ContentType() string { return labels.ContentType_JSONLines }
// Marshal implements Framing.
func (*jsonFraming) Marshal(msg Frameable, bw *bufio.Writer) error {
if jf, ok := msg.(JSONMarshalerTo); ok {
_, err := jf.MarshalJSONTo(bw)
return err
}
return json.NewEncoder(bw).Encode(msg)
}
// NewUnmarshalFunc returns an UnmarshalFunc which decodes JSON messages from the Reader.
func (*jsonFraming) NewUnmarshalFunc(r *bufio.Reader) UnmarshalFunc {
// We cannot use json.NewDecoder, as it buffers internally beyond the
// precise boundary of a JSON message.
return func(f Frameable) (err error) {
var l []byte
if l, err = UnpackLine(r); err != nil {
return
}
if jf, ok := f.(json.Unmarshaler); ok {
return jf.UnmarshalJSON(l)
}
return json.Unmarshal(l, f)
}
}
func init() { RegisterFraming(new(jsonFraming)) }