diff --git a/envelopes.go b/envelopes.go index 34a6e3f..9768131 100644 --- a/envelopes.go +++ b/envelopes.go @@ -37,6 +37,8 @@ func ParseMessage(message []byte) Envelope { case bytes.Contains(label, []byte("CLOSE")): x := CloseEnvelope("") v = &x + case bytes.Contains(label, []byte("CLOSED")): + v = &ClosedEnvelope{} default: return nil } @@ -255,12 +257,41 @@ func (v *CloseEnvelope) UnmarshalJSON(data []byte) error { func (v CloseEnvelope) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} - w.RawString(`["CLOSE",`) + w.RawString(`["CLOSED",`) w.Raw(json.Marshal(string(v))) w.RawString(`]`) return w.BuildBytes() } +type ClosedEnvelope struct { + SubscriptionID string + Reason string +} + +func (_ ClosedEnvelope) Label() string { return "CLOSED" } + +func (v *ClosedEnvelope) UnmarshalJSON(data []byte) error { + r := gjson.ParseBytes(data) + arr := r.Array() + switch len(arr) { + case 3: + *v = ClosedEnvelope{arr[1].Str, arr[2].Str} + return nil + default: + return fmt.Errorf("failed to decode CLOSED envelope") + } +} + +func (v ClosedEnvelope) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + w.RawString(`["CLOSED",`) + w.Raw(json.Marshal(string(v.SubscriptionID))) + w.RawString(`,`) + w.Raw(json.Marshal(v.Reason)) + w.RawString(`]`) + return w.BuildBytes() +} + type OKEnvelope struct { EventID string OK bool diff --git a/envelopes_test.go b/envelopes_test.go index b033fc6..b5410ab 100644 --- a/envelopes_test.go +++ b/envelopes_test.go @@ -88,6 +88,19 @@ func TestOKEnvelopeEncodingAndDecoding(t *testing.T) { } } +func TestClosedEnvelopeEncodingAndDecoding(t *testing.T) { + src := `["CLOSED","_","error: something went wrong"]` + var env ClosedEnvelope + json.Unmarshal([]byte(src), &env) + if env.SubscriptionID != "_" { + t.Error("failed to decode CLOSED") + } + + if res, _ := json.Marshal(env); string(res) != src { + t.Errorf("failed to encode CLOSED: expected '%s', got '%s'", src, string(res)) + } +} + func TestAuthEnvelopeEncodingAndDecoding(t *testing.T) { authEnvelopes := []string{ `["AUTH","kjsabdlasb aslkd kasndkad \"as.kdnbskadb"]`,