closeenvelope.go raw

   1  // Package closeenvelope provides the encoder for the client message CLOSE which
   2  // is a request to terminate a subscription.
   3  package closeenvelope
   4  
   5  import (
   6  	"io"
   7  
   8  	"next.orly.dev/pkg/nostr/encoders/envelopes"
   9  	"next.orly.dev/pkg/nostr/encoders/text"
  10  	"next.orly.dev/pkg/nostr/interfaces/codec"
  11  	"next.orly.dev/pkg/lol/chk"
  12  )
  13  
  14  // L is the label associated with this type of codec.Envelope.
  15  const L = "CLOSE"
  16  
  17  // T is a CLOSE envelope, which is a signal from client to relay to stop a
  18  // specified subscription.
  19  type T struct {
  20  	ID []byte
  21  }
  22  
  23  var _ codec.Envelope = (*T)(nil)
  24  
  25  // New creates an empty new standard formatted closeenvelope.T.
  26  func New() *T { return new(T) }
  27  
  28  // NewFrom creates a new closeenvelope.T populated with subscription ID.
  29  func NewFrom(id []byte) *T { return &T{ID: id} }
  30  
  31  // Label returns the label of a closeenvelope.T.
  32  func (en *T) Label() string { return L }
  33  
  34  // Write the closeenvelope.T to a provided io.Writer.
  35  func (en *T) Write(w io.Writer) (err error) {
  36  	_, err = w.Write(en.Marshal(nil))
  37  	return
  38  }
  39  
  40  // Marshal a closeenvelope.T envelope in minified JSON, appending to a provided
  41  // destination slice.
  42  func (en *T) Marshal(dst []byte) (b []byte) {
  43  	b = dst
  44  	b = envelopes.Marshal(
  45  		b, L,
  46  		func(bst []byte) (o []byte) {
  47  			o = bst
  48  			o = append(o, '"')
  49  			o = append(o, en.ID...)
  50  			o = append(o, '"')
  51  			return
  52  		},
  53  	)
  54  	return
  55  }
  56  
  57  // Unmarshal a closeenvelope.T from minified JSON, returning the remainder after
  58  // the end of the envelope.
  59  func (en *T) Unmarshal(b []byte) (r []byte, err error) {
  60  	r = b
  61  	if en.ID, r, err = text.UnmarshalQuoted(r); chk.E(err) {
  62  		return
  63  	}
  64  	if r, err = envelopes.SkipToTheEnd(r); chk.E(err) {
  65  		return
  66  	}
  67  	return
  68  }
  69  
  70  // Parse reads a CLOSE envelope from minified JSON into a newly allocated
  71  // closeenvelope.T.
  72  func Parse(b []byte) (t *T, rem []byte, err error) {
  73  	t = New()
  74  	if rem, err = t.Unmarshal(b); chk.E(err) {
  75  		return
  76  	}
  77  	return
  78  }
  79