Files
realy/eventid/eventid.go
mleku bbebbe2b02 Add tracing with lol.Tracer in multiple functions.
Introduced `lol.Tracer` for function entry/exit logging across various packages. This improves traceability and debugging of function executions while preserving existing behavior. Removed unused files `doc.go` and `nothing.go` to clean up the repository.
2025-06-29 07:32:24 +01:00

160 lines
3.8 KiB
Go

// Package eventid is a codec for managing nostr event Ids (hash of the
// canonical form of a nostr event).
package eventid
import (
"lukechampine.com/frand"
"realy.lol/chk"
"realy.lol/errorf"
"realy.lol/hex"
"realy.lol/log"
"realy.lol/lol"
"realy.lol/sha256"
)
const Len = sha256.Size
// T is the SHA256 hash in hexadecimal of the canonical form of an event as
// produced by the output of T.ToCanonical().Bytes().
type T [Len]byte
// New creates a new eventid.T. This is actually more wordy than simply creating a &T{} via
// slice literal.
func New() (ei *T) { return &T{} }
// NewWith creates an eventid.T out of bytes or string but assumes it is binary
// and that it is the right length. The result is either truncated or padded automatically by
// the use of the "copy" operation.
func NewWith[V string | []byte](s V) (ei *T) {
lol.Tracer("New", s)
defer func() { lol.Tracer("end New", ei) }()
id := T{}
copy(id[:], s)
ei = &id
return
}
// Set the value of an eventid.T with checking of the length before copying it.
func (ei *T) Set(b []byte) (err error) {
lol.Tracer("Set", b)
defer func() { lol.Tracer("end Set", err) }()
if ei == nil {
err = errorf.E("event id is nil")
return
}
if len(b) != Len {
err = errorf.E("Id bytes incorrect size, got %d require %d",
len(b), Len)
return
}
copy(ei[:], b)
return
}
// NewFromBytes creates a new eventid.T from the raw event Id hash.
func NewFromBytes(b []byte) (ei *T, err error) {
lol.Tracer("NewFromBytes", b)
defer func() { lol.Tracer("end NewFromBytes", ei, err) }()
ei = New()
if err = ei.Set(b); chk.E(err) {
return
}
return
}
// String renders an eventid.T as a string.
func (ei *T) String() string {
if ei == nil {
return ""
}
return hex.Enc(ei[:])
}
// ByteString renders an eventid.T as bytes in ASCII hex.
func (ei *T) ByteString(src []byte) (b []byte) {
lol.Tracer("ByteString", src)
defer func() { lol.Tracer("end ByteString", b) }()
b = hex.EncAppend(src, ei[:])
return
}
// Bytes returns the raw bytes of the eventid.T.
func (ei *T) Bytes() (b []byte) { return ei[:] }
// Len returns the length of the eventid.T.
func (ei *T) Len() int {
if ei == nil {
log.W.Ln("nil event id")
return 0
}
return len(ei)
}
// Equal tests whether another eventid.T is the same.
func (ei *T) Equal(ei2 *T) (eq bool) {
if ei == nil || ei2 == nil {
log.W.Ln("can't compare to nil event id")
return
}
return *ei == *ei2
}
// Marshal renders the eventid.T into JSON.
func (ei *T) Marshal(dst []byte) (b []byte) {
lol.Tracer("Marshal", dst)
defer func() { lol.Tracer("end Marshal", b) }()
b = dst
b = make([]byte, 0, 2*Len+2)
b = append(b, '"')
hex.EncAppend(b, ei[:])
b = append(b, '"')
return
}
// Unmarshal decodes a JSON encoded eventid.T.
func (ei *T) Unmarshal(b []byte) (rem []byte, err error) {
lol.Tracer("Unmarshal", b)
defer func() { lol.Tracer("end Unmarshal", rem, err) }()
// trim off the quotes.
b = b[1 : 2*Len+1]
if len(b) != 2*Len {
err = errorf.E("event Id hex incorrect size, got %d require %d",
len(b), 2*Len)
log.E.Ln(string(b))
return
}
var bb []byte
if bb, err = hex.Dec(string(b)); chk.E(err) {
return
}
copy(ei[:], bb)
return
}
// NewFromString inspects a string and ensures it is a valid, 64 character long
// hexadecimal string, returns the string coerced to the type.
func NewFromString(s string) (ei *T, err error) {
lol.Tracer("NewFromString", s)
defer func() { lol.Tracer("end NewFromString", ei, err) }()
if len(s) != 2*Len {
return nil, errorf.E("event Id hex wrong size, got %d require %d",
len(s), 2*Len)
}
ei = &T{}
b := make([]byte, 0, Len)
b, err = hex.DecAppend(b, []byte(s))
copy(ei[:], b)
return
}
// Gen creates a fake pseudorandom generated event Id for tests.
func Gen() (ei *T) {
lol.Tracer("Gen")
defer func() { lol.Tracer("end Gen", ei) }()
b := frand.Bytes(Len)
ei = &T{}
copy(ei[:], b)
return
}