// Package noticeenvelope is a codec for the NOTICE envelope, which is used to // serve (mostly ignored) messages that are supposed to be shown to a user in // the client. package noticeenvelope import ( "io" "lol.mleku.dev/chk" "next.orly.dev/pkg/encoders/envelopes" "next.orly.dev/pkg/encoders/text" "next.orly.dev/pkg/interfaces/codec" "next.orly.dev/pkg/utils/constraints" ) // L is the label associated with this type of codec.Envelope. const L = "NOTICE" // T is a NOTICE envelope, intended to convey information to the user about the // state of the relay connection. This thing is rarely displayed on clients // except sometimes in event logs. type T struct { Message []byte } var _ codec.Envelope = (*T)(nil) // New creates a new empty NOTICE noticeenvelope.T. func New() *T { return &T{} } // NewFrom creates a new noticeenvelope.T with a provided message. func NewFrom[V constraints.Bytes](msg V) *T { return &T{Message: []byte(msg)} } // Label returns the label of a NOTICE envelope. func (en *T) Label() string { return L } // Write the NOTICE T to a provided io.Writer. func (en *T) Write(w io.Writer) (err error) { _, err = w.Write(en.Marshal(nil)) return } // Marshal a NOTICE envelope in minified JSON into an noticeenvelope.T, // appending to a provided destination slice. Note that this ensures correct // string escaping on the Reason field. func (en *T) Marshal(dst []byte) (b []byte) { var err error _ = err b = dst b = envelopes.Marshal( b, L, func(bst []byte) (o []byte) { o = bst o = append(o, '"') o = text.NostrEscape(o, en.Message) o = append(o, '"') return }, ) return } // Unmarshal a noticeenvelope.T from minified JSON, returning the remainder // after the end of the envelope. Note that this ensures the Reason string is // correctly unescaped by NIP-01 escaping rules. func (en *T) Unmarshal(b []byte) (r []byte, err error) { r = b if en.Message, r, err = text.UnmarshalQuoted(r); chk.E(err) { return } if r, err = envelopes.SkipToTheEnd(r); chk.E(err) { return } return } // Parse reads a NOTICE envelope in minified JSON into a newly allocated // noticeenvelope.T. func Parse(b []byte) (t *T, rem []byte, err error) { t = New() if rem, err = t.Unmarshal(b); chk.E(err) { return } return }