You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
4.6 KiB
179 lines
4.6 KiB
// Package eventenvelope is a codec for the event Submission request EVENT envelope |
|
// (client) and event Result (to a REQ) from a relay. |
|
package eventenvelope |
|
|
|
import ( |
|
"io" |
|
|
|
"encoders.orly/envelopes" |
|
"encoders.orly/event" |
|
"encoders.orly/text" |
|
"interfaces.orly/codec" |
|
"lol.mleku.dev/chk" |
|
"lol.mleku.dev/errorf" |
|
"utils.orly/bufpool" |
|
"utils.orly/units" |
|
"utils.orly/constraints" |
|
) |
|
|
|
// L is the label associated with this type of codec.Envelope. |
|
const L = "EVENT" |
|
|
|
// Submission is a request from a client for a realy to store an event. |
|
type Submission struct { |
|
*event.E |
|
} |
|
|
|
var _ codec.Envelope = (*Submission)(nil) |
|
|
|
// NewSubmission creates an empty new eventenvelope.Submission. |
|
func NewSubmission() *Submission { return &Submission{E: &event.E{}} } |
|
|
|
// NewSubmissionWith creates a new eventenvelope.Submission with a provided event.E. |
|
func NewSubmissionWith(ev *event.E) *Submission { return &Submission{E: ev} } |
|
|
|
// Label returns the label of a event eventenvelope.Submission envelope. |
|
func (en *Submission) Label() string { return L } |
|
|
|
func (en *Submission) Id() []byte { return en.E.ID } |
|
|
|
// Write the Submission to a provided io.Writer. |
|
func (en *Submission) Write(w io.Writer) (err error) { |
|
_, err = w.Write(en.Marshal(nil)) |
|
return |
|
} |
|
|
|
// Marshal an event Submission envelope in minified JSON, appending to a |
|
// provided destination slice. |
|
func (en *Submission) Marshal(dst []byte) (b []byte) { |
|
var err error |
|
// if the destination capacity is not large enough, allocate a new |
|
// destination slice. |
|
if en.EstimateSize() >= cap(dst) { |
|
dst = make([]byte, 0, en.EstimateSize()+units.Kb) |
|
} |
|
b = dst |
|
b = envelopes.Marshal( |
|
b, L, |
|
func(bst []byte) (o []byte) { |
|
o = bst |
|
o = en.E.Marshal(o) |
|
return |
|
}, |
|
) |
|
_ = err |
|
return |
|
} |
|
|
|
// Unmarshal an event eventenvelope.Submission from minified JSON, returning the |
|
// remainder after the end of the envelope. |
|
func (en *Submission) Unmarshal(b []byte) (r []byte, err error) { |
|
r = b |
|
en.E = event.New() |
|
if r, err = en.E.Unmarshal(r); chk.T(err) { |
|
return |
|
} |
|
buf := bufpool.Get() |
|
r = en.E.Marshal(buf) |
|
if r, err = envelopes.SkipToTheEnd(r); chk.E(err) { |
|
return |
|
} |
|
return |
|
} |
|
|
|
// ParseSubmission reads an event envelope Submission from minified JSON into a newly |
|
// allocated eventenvelope.Submission. |
|
func ParseSubmission(b []byte) (t *Submission, rem []byte, err error) { |
|
t = NewSubmission() |
|
if rem, err = t.Unmarshal(b); chk.E(err) { |
|
return |
|
} |
|
return |
|
} |
|
|
|
// Result is an event matching a filter associated with a subscription. |
|
type Result struct { |
|
Subscription []byte |
|
Event *event.E |
|
} |
|
|
|
var _ codec.Envelope = (*Result)(nil) |
|
|
|
// NewResult creates a new empty eventenvelope.Result. |
|
func NewResult() *Result { return &Result{} } |
|
|
|
// NewResultWith creates a new eventenvelope.Result with a provided |
|
// subscription.Id string and event.E. |
|
func NewResultWith[V constraints.Bytes](s V, ev *event.E) ( |
|
res *Result, err error, |
|
) { |
|
if len(s) < 0 || len(s) > 64 { |
|
err = errorf.E("subscription id must be length > 0 and <= 64") |
|
return |
|
} |
|
return &Result{[]byte(s), ev}, nil |
|
} |
|
|
|
func (en *Result) Id() []byte { return en.Event.ID } |
|
|
|
// Label returns the label of a event eventenvelope.Result envelope. |
|
func (en *Result) Label() string { return L } |
|
|
|
// Write the eventenvelope.Result to a provided io.Writer. |
|
func (en *Result) Write(w io.Writer) (err error) { |
|
_, err = w.Write(en.Marshal(nil)) |
|
return |
|
} |
|
|
|
// Marshal an eventenvelope.Result envelope in minified JSON, appending to a |
|
// provided destination slice. |
|
func (en *Result) Marshal(dst []byte) (b []byte) { |
|
// if the destination capacity is not large enough, allocate a new |
|
// destination slice. |
|
if en.Event.EstimateSize() >= cap(dst) { |
|
dst = make([]byte, 0, en.Event.EstimateSize()+units.Kb) |
|
} |
|
b = dst |
|
var err error |
|
b = envelopes.Marshal( |
|
b, L, |
|
func(bst []byte) (o []byte) { |
|
o = bst |
|
o = append(o, '"') |
|
o = append(o, en.Subscription...) |
|
o = append(o, '"') |
|
o = append(o, ',') |
|
o = en.Event.Marshal(o) |
|
return |
|
}, |
|
) |
|
_ = err |
|
return |
|
} |
|
|
|
// Unmarshal an event Result envelope from minified JSON, returning the |
|
// remainder after the end of the envelope. |
|
func (en *Result) Unmarshal(b []byte) (r []byte, err error) { |
|
r = b |
|
if en.Subscription, r, err = text.UnmarshalQuoted(r); chk.E(err) { |
|
return |
|
} |
|
en.Event = event.New() |
|
if r, err = en.Event.Unmarshal(r); err != nil { |
|
return |
|
} |
|
if r, err = envelopes.SkipToTheEnd(r); chk.E(err) { |
|
return |
|
} |
|
return |
|
} |
|
|
|
// ParseResult allocates a new eventenvelope.Result and unmarshalls an EVENT |
|
// envelope into it. |
|
func ParseResult(b []byte) (t *Result, rem []byte, err error) { |
|
t = NewResult() |
|
if rem, err = t.Unmarshal(b); err != nil { |
|
return |
|
} |
|
return |
|
}
|
|
|