migrate to new nostr library
This commit is contained in:
@@ -1,76 +0,0 @@
|
||||
package bufpool
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"next.orly.dev/pkg/utils/units"
|
||||
)
|
||||
|
||||
const (
|
||||
// BufferSize is the size of each buffer in the pool (1kb)
|
||||
BufferSize = units.Kb
|
||||
)
|
||||
|
||||
type B []byte
|
||||
|
||||
func (b B) ToBytes() []byte { return b }
|
||||
|
||||
var Pool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
// Create a new buffer when the pool is empty
|
||||
b := make([]byte, 0, BufferSize)
|
||||
// log.T.C(
|
||||
// func() string {
|
||||
// ptr := unsafe.SliceData(b)
|
||||
// return fmt.Sprintf("creating buffer at: %p", ptr)
|
||||
// },
|
||||
// )
|
||||
return B(b)
|
||||
},
|
||||
}
|
||||
|
||||
// Get returns a buffer from the pool or creates a new one if the pool is empty.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// buf := bufpool.Get()
|
||||
// defer bufpool.Put(buf)
|
||||
// // Use buf...
|
||||
func Get() B {
|
||||
b := Pool.Get().(B)
|
||||
// log.T.C(
|
||||
// func() string {
|
||||
// ptr := unsafe.SliceData(b)
|
||||
// return fmt.Sprintf("getting buffer at: %p", ptr)
|
||||
// },
|
||||
// )
|
||||
return b
|
||||
}
|
||||
|
||||
// Put returns a buffer to the pool.
|
||||
// Buffers should be returned to the pool when no longer needed to allow reuse.
|
||||
func Put(b B) {
|
||||
for i := range b {
|
||||
(b)[i] = 0
|
||||
}
|
||||
b = b[:0]
|
||||
// log.T.C(
|
||||
// func() string {
|
||||
// ptr := unsafe.SliceData(b)
|
||||
// return fmt.Sprintf("returning to buffer: %p", ptr)
|
||||
// },
|
||||
// )
|
||||
Pool.Put(b)
|
||||
}
|
||||
|
||||
// PutBytes returns a buffer was not necessarily created by Get().
|
||||
func PutBytes(b []byte) {
|
||||
// log.T.C(
|
||||
// func() string {
|
||||
// ptr := unsafe.SliceData(b)
|
||||
// return fmt.Sprintf("returning bytes to buffer: %p", ptr)
|
||||
// },
|
||||
// )
|
||||
b = b[:0]
|
||||
Put(b)
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package constraints
|
||||
|
||||
type Bytes interface {
|
||||
~string | ~[]byte
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package utils
|
||||
|
||||
import "next.orly.dev/pkg/utils/constraints"
|
||||
import "git.mleku.dev/mleku/nostr/utils/constraints"
|
||||
|
||||
func FastEqual[A constraints.Bytes, B constraints.Bytes](a A, b B) (same bool) {
|
||||
if len(a) != len(b) {
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
// Package normalize is a set of tools for cleaning up URL s and formatting
|
||||
// nostr OK and CLOSED messages.
|
||||
package normalize
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"lol.mleku.dev/chk"
|
||||
"lol.mleku.dev/log"
|
||||
"next.orly.dev/pkg/encoders/ints"
|
||||
"next.orly.dev/pkg/utils/constraints"
|
||||
)
|
||||
|
||||
var (
|
||||
hp = bytes.HasPrefix
|
||||
WS = []byte("ws://")
|
||||
WSS = []byte("wss://")
|
||||
HTTP = []byte("http://")
|
||||
HTTPS = []byte("https://")
|
||||
)
|
||||
|
||||
// URL normalizes the URL
|
||||
//
|
||||
// - Adds wss:// to addresses without a port, or with 443 that have no protocol
|
||||
// prefix
|
||||
//
|
||||
// - Adds ws:// to addresses with any other port
|
||||
//
|
||||
// - Converts http/s to ws/s
|
||||
func URL[V constraints.Bytes](v V) (b []byte) {
|
||||
u := []byte(v)
|
||||
if len(u) == 0 {
|
||||
return nil
|
||||
}
|
||||
u = bytes.TrimSpace(u)
|
||||
u = bytes.ToLower(u)
|
||||
// if the address has a port number, we can probably assume it is insecure
|
||||
// websocket as most public or production relays have a domain name and a
|
||||
// well-known port 80 or 443 and thus no port number.
|
||||
//
|
||||
// if a protocol prefix is present, we assume it is already complete.
|
||||
// Converting http/s to websocket-equivalent will be done later anyway.
|
||||
if bytes.Contains(u, []byte(":")) &&
|
||||
!(hp(u, HTTP) || hp(u, HTTPS) || hp(u, WS) || hp(u, WSS)) {
|
||||
|
||||
split := bytes.Split(u, []byte(":"))
|
||||
if len(split) != 2 {
|
||||
log.D.F("Error: more than one ':' in URL: '%s'", u)
|
||||
// this is a malformed URL if it has more than one ":", return empty
|
||||
// since this function does not return an error explicitly.
|
||||
return
|
||||
}
|
||||
p := ints.New(0)
|
||||
_, err := p.Unmarshal(split[1])
|
||||
if chk.E(err) {
|
||||
log.D.F("Error normalizing URL '%s': %s", u, err)
|
||||
// again, without an error, we must return nil
|
||||
return
|
||||
}
|
||||
if p.Uint64() > 65535 {
|
||||
log.D.F(
|
||||
"Port on address %d: greater than maximum 65535",
|
||||
p.Uint64(),
|
||||
)
|
||||
return
|
||||
}
|
||||
// if the port is explicitly set to 443 we assume it is wss:// and drop
|
||||
// the port.
|
||||
if p.Uint16() == 443 {
|
||||
u = append(WSS, split[0]...)
|
||||
} else {
|
||||
u = append(WSS, u...)
|
||||
}
|
||||
}
|
||||
|
||||
// if the prefix isn't specified as http/s or websocket, assume secure
|
||||
// websocket and add wss prefix (this is the most common).
|
||||
if !(hp(u, HTTP) || hp(u, HTTPS) || hp(u, WS) || hp(u, WSS)) {
|
||||
u = append(WSS, u...)
|
||||
}
|
||||
var err error
|
||||
var p *url.URL
|
||||
if p, err = url.Parse(string(u)); chk.E(err) {
|
||||
return
|
||||
}
|
||||
// convert http/s to ws/s
|
||||
switch p.Scheme {
|
||||
case "https":
|
||||
p.Scheme = "wss"
|
||||
case "http":
|
||||
p.Scheme = "ws"
|
||||
}
|
||||
// remove trailing path slash
|
||||
p.Path = string(bytes.TrimRight([]byte(p.Path), "/"))
|
||||
return []byte(p.String())
|
||||
}
|
||||
|
||||
// Msg constructs a properly formatted message with a machine-readable prefix
|
||||
// for OK and CLOSED envelopes.
|
||||
func Msg(prefix Reason, format string, params ...any) []byte {
|
||||
if len(prefix) < 1 {
|
||||
prefix = Error
|
||||
}
|
||||
return []byte(fmt.Sprintf(prefix.S()+": "+format, params...))
|
||||
}
|
||||
|
||||
// MsgString constructs a properly formatted message with a machine-readable prefix
|
||||
// for OK and CLOSED envelopes.
|
||||
func MsgString(prefix Reason, format string, params ...any) string {
|
||||
if len(prefix) < 1 {
|
||||
prefix = Error
|
||||
}
|
||||
return fmt.Sprintf(prefix.S()+": "+format, params...)
|
||||
}
|
||||
|
||||
// Reason is the machine-readable prefix before the colon in an OK or CLOSED
|
||||
// envelope message. Below are the most common kinds that are mentioned in
|
||||
// NIP-01.
|
||||
type Reason []byte
|
||||
|
||||
var (
|
||||
AuthRequired = Reason("auth-required")
|
||||
PoW = Reason("pow")
|
||||
Duplicate = Reason("duplicate")
|
||||
Blocked = Reason("blocked")
|
||||
RateLimited = Reason("rate-limited")
|
||||
Invalid = Reason("invalid")
|
||||
Error = Reason("error")
|
||||
Unsupported = Reason("unsupported")
|
||||
Restricted = Reason("restricted")
|
||||
)
|
||||
|
||||
// S returns the Reason as a string
|
||||
func (r Reason) S() string { return string(r) }
|
||||
|
||||
// B returns the Reason as a byte slice.
|
||||
func (r Reason) B() []byte { return r }
|
||||
|
||||
// IsPrefix returns whether a text contains the same Reason prefix.
|
||||
func (r Reason) IsPrefix(reason []byte) bool {
|
||||
return bytes.HasPrefix(
|
||||
reason, r.B(),
|
||||
)
|
||||
}
|
||||
|
||||
// F allows creation of a full Reason text with a printf style format.
|
||||
func (r Reason) F(format string, params ...any) []byte {
|
||||
return Msg(
|
||||
r, format, params...,
|
||||
)
|
||||
}
|
||||
|
||||
// Errorf allows creation of a full Reason text with a printf style as an error.
|
||||
func (r Reason) Errorf(format string, params ...any) (err error) {
|
||||
return errors.New(
|
||||
MsgString(
|
||||
r, format, params...,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package normalize
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestURL(t *testing.T) {
|
||||
fmt.Println(URL([]byte("")))
|
||||
fmt.Println(URL([]byte("wss://x.com/y")))
|
||||
fmt.Println(URL([]byte("wss://x.com/y/")))
|
||||
fmt.Println(URL([]byte("http://x.com/y")))
|
||||
fmt.Println(URL(URL([]byte("http://x.com/y"))))
|
||||
fmt.Println(URL([]byte("wss://x.com")))
|
||||
fmt.Println(URL([]byte("wss://x.com/")))
|
||||
fmt.Println(URL(URL(URL([]byte("wss://x.com/")))))
|
||||
fmt.Println(URL([]byte("x.com")))
|
||||
fmt.Println(URL([]byte("x.com/")))
|
||||
fmt.Println(URL([]byte("x.com////")))
|
||||
fmt.Println(URL([]byte("x.com/?x=23")))
|
||||
|
||||
// Output:
|
||||
//
|
||||
// wss://x.com/y
|
||||
// wss://x.com/y
|
||||
// ws://x.com/y
|
||||
// ws://x.com/y
|
||||
// wss://x.com
|
||||
// wss://x.com
|
||||
// wss://x.com
|
||||
// wss://x.com
|
||||
// wss://x.com
|
||||
// wss://x.com
|
||||
// wss://x.com?x=23
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// Package number implements a simple number list, used with relayinfo package
|
||||
// for NIP support lists.
|
||||
package number
|
||||
|
||||
import "fmt"
|
||||
|
||||
// List is a simple list of numbers with a sort implementation and number match.
|
||||
type List []int
|
||||
|
||||
func (l List) Len() int { return len(l) }
|
||||
func (l List) Less(i, j int) bool { return l[i] < l[j] }
|
||||
func (l List) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
|
||||
|
||||
// HasNumber returns true if the list contains a given number
|
||||
func (l List) HasNumber(n int) (idx int, has bool) {
|
||||
for idx = range l {
|
||||
if l[idx] == n {
|
||||
has = true
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// String outputs a number.List as a minified JSON array.
|
||||
func (l List) String() (s string) {
|
||||
s += "["
|
||||
for i := range l {
|
||||
if i > 0 {
|
||||
s += ","
|
||||
}
|
||||
s += fmt.Sprint(l[i])
|
||||
}
|
||||
s += "]"
|
||||
return
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package pointers
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"next.orly.dev/pkg/encoders/timestamp"
|
||||
)
|
||||
|
||||
// PointerToValue is a generic interface (type constraint) to refer to any
|
||||
// pointer to almost any kind of common type of value.
|
||||
//
|
||||
// see the utils/values package for a set of methods to accept these values and
|
||||
// return the correct type pointer to them.
|
||||
type PointerToValue interface {
|
||||
~*uint | ~*int | ~*uint8 | ~*uint16 | ~*uint32 | ~*uint64 | ~*int8 | ~*int16 | ~*int32 |
|
||||
~*int64 | ~*float32 | ~*float64 | ~*string | ~*[]string | ~*time.Time | ~*time.Duration |
|
||||
~*[]byte | ~*[][]byte | ~*timestamp.T
|
||||
}
|
||||
|
||||
// Present determines whether there is a value for a PointerToValue type.
|
||||
func Present[V PointerToValue](i V) bool {
|
||||
return i != nil
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
// Package units is a convenient set of names designating data sizes in bytes
|
||||
// using common ISO names (base 10).
|
||||
package units
|
||||
|
||||
const (
|
||||
Kilobyte = 1000
|
||||
Kb = Kilobyte
|
||||
Megabyte = Kilobyte * Kilobyte
|
||||
Mb = Megabyte
|
||||
Gigabyte = Megabyte * Kilobyte
|
||||
Gb = Gigabyte
|
||||
)
|
||||
@@ -1,95 +0,0 @@
|
||||
package values
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// ToUintPointer returns a pointer to the uint value passed in.
|
||||
func ToUintPointer(v uint) *uint {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToIntPointer returns a pointer to the int value passed in.
|
||||
func ToIntPointer(v int) *int {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToUint8Pointer returns a pointer to the uint8 value passed in.
|
||||
func ToUint8Pointer(v uint8) *uint8 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToUint16Pointer returns a pointer to the uint16 value passed in.
|
||||
func ToUint16Pointer(v uint16) *uint16 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToUint32Pointer returns a pointer to the uint32 value passed in.
|
||||
func ToUint32Pointer(v uint32) *uint32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToUint64Pointer returns a pointer to the uint64 value passed in.
|
||||
func ToUint64Pointer(v uint64) *uint64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToInt8Pointer returns a pointer to the int8 value passed in.
|
||||
func ToInt8Pointer(v int8) *int8 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToInt16Pointer returns a pointer to the int16 value passed in.
|
||||
func ToInt16Pointer(v int16) *int16 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToInt32Pointer returns a pointer to the int32 value passed in.
|
||||
func ToInt32Pointer(v int32) *int32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToInt64Pointer returns a pointer to the int64 value passed in.
|
||||
func ToInt64Pointer(v int64) *int64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToFloat32Pointer returns a pointer to the float32 value passed in.
|
||||
func ToFloat32Pointer(v float32) *float32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToFloat64Pointer returns a pointer to the float64 value passed in.
|
||||
func ToFloat64Pointer(v float64) *float64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToStringPointer returns a pointer to the string value passed in.
|
||||
func ToStringPointer(v string) *string {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToStringSlicePointer returns a pointer to the []string value passed in.
|
||||
func ToStringSlicePointer(v []string) *[]string {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToTimePointer returns a pointer to the time.Time value passed in.
|
||||
func ToTimePointer(v time.Time) *time.Time {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToDurationPointer returns a pointer to the time.Duration value passed in.
|
||||
func ToDurationPointer(v time.Duration) *time.Duration {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToBytesPointer returns a pointer to the []byte value passed in.
|
||||
func ToBytesPointer(v []byte) *[]byte {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToByteSlicesPointer returns a pointer to the [][]byte value passed in.
|
||||
func ToByteSlicesPointer(v [][]byte) *[][]byte {
|
||||
return &v
|
||||
}
|
||||
Reference in New Issue
Block a user