diff --git a/helpers.go b/helpers.go new file mode 100644 index 0000000..019e6c4 --- /dev/null +++ b/helpers.go @@ -0,0 +1,89 @@ +package nostr + +import ( + "sync" + + "github.com/dgraph-io/ristretto/z" + "golang.org/x/exp/constraints" +) + +const MAX_LOCKS = 50 + +var namedMutexPool = make([]sync.Mutex, MAX_LOCKS) + +func namedLock(name string) (unlock func()) { + idx := z.MemHashString(name) % MAX_LOCKS + namedMutexPool[idx].Lock() + return namedMutexPool[idx].Unlock +} + +func similar[E constraints.Ordered](as, bs []E) bool { + if len(as) != len(bs) { + return false + } + + for _, a := range as { + for _, b := range bs { + if b == a { + goto next + } + } + // didn't find a B that corresponded to the current A + return false + + next: + continue + } + + return true +} + +// Escaping strings for JSON encoding according to RFC8259. +// Also encloses result in quotation marks "". +func escapeString(dst []byte, s string) []byte { + dst = append(dst, '"') + for i := 0; i < len(s); i++ { + c := s[i] + switch { + case c == '"': + // quotation mark + dst = append(dst, []byte{'\\', '"'}...) + case c == '\\': + // reverse solidus + dst = append(dst, []byte{'\\', '\\'}...) + case c >= 0x20: + // default, rest below are control chars + dst = append(dst, c) + case c == 0x08: + dst = append(dst, []byte{'\\', 'b'}...) + case c < 0x09: + dst = append(dst, []byte{'\\', 'u', '0', '0', '0', '0' + c}...) + case c == 0x09: + dst = append(dst, []byte{'\\', 't'}...) + case c == 0x0a: + dst = append(dst, []byte{'\\', 'n'}...) + case c == 0x0c: + dst = append(dst, []byte{'\\', 'f'}...) + case c == 0x0d: + dst = append(dst, []byte{'\\', 'r'}...) + case c < 0x10: + dst = append(dst, []byte{'\\', 'u', '0', '0', '0', 0x57 + c}...) + case c < 0x1a: + dst = append(dst, []byte{'\\', 'u', '0', '0', '1', 0x20 + c}...) + case c < 0x20: + dst = append(dst, []byte{'\\', 'u', '0', '0', '1', 0x47 + c}...) + } + } + dst = append(dst, '"') + return dst +} + +func arePointerValuesEqual[V comparable](a *V, b *V) bool { + if a == nil && b == nil { + return true + } + if a != nil && b != nil { + return *a == *b + } + return false +} diff --git a/utils.go b/utils.go index fcd07d9..874ced0 100644 --- a/utils.go +++ b/utils.go @@ -3,83 +3,8 @@ package nostr import ( "net/url" "strings" - "sync" - - "github.com/dgraph-io/ristretto/z" - "golang.org/x/exp/constraints" ) -const MAX_LOCKS = 50 - -var namedMutexPool = make([]sync.Mutex, MAX_LOCKS) - -func namedLock(name string) (unlock func()) { - idx := z.MemHashString(name) % MAX_LOCKS - namedMutexPool[idx].Lock() - return namedMutexPool[idx].Unlock -} - -func similar[E constraints.Ordered](as, bs []E) bool { - if len(as) != len(bs) { - return false - } - - for _, a := range as { - for _, b := range bs { - if b == a { - goto next - } - } - // didn't find a B that corresponded to the current A - return false - - next: - continue - } - - return true -} - -// Escaping strings for JSON encoding according to RFC8259. -// Also encloses result in quotation marks "". -func escapeString(dst []byte, s string) []byte { - dst = append(dst, '"') - for i := 0; i < len(s); i++ { - c := s[i] - switch { - case c == '"': - // quotation mark - dst = append(dst, []byte{'\\', '"'}...) - case c == '\\': - // reverse solidus - dst = append(dst, []byte{'\\', '\\'}...) - case c >= 0x20: - // default, rest below are control chars - dst = append(dst, c) - case c == 0x08: - dst = append(dst, []byte{'\\', 'b'}...) - case c < 0x09: - dst = append(dst, []byte{'\\', 'u', '0', '0', '0', '0' + c}...) - case c == 0x09: - dst = append(dst, []byte{'\\', 't'}...) - case c == 0x0a: - dst = append(dst, []byte{'\\', 'n'}...) - case c == 0x0c: - dst = append(dst, []byte{'\\', 'f'}...) - case c == 0x0d: - dst = append(dst, []byte{'\\', 'r'}...) - case c < 0x10: - dst = append(dst, []byte{'\\', 'u', '0', '0', '0', 0x57 + c}...) - case c < 0x1a: - dst = append(dst, []byte{'\\', 'u', '0', '0', '1', 0x20 + c}...) - case c < 0x20: - dst = append(dst, []byte{'\\', 'u', '0', '0', '1', 0x47 + c}...) - } - } - dst = append(dst, '"') - return dst -} - func IsValidRelayURL(u string) bool { parsed, err := url.Parse(u) if err != nil { @@ -93,13 +18,3 @@ func IsValidRelayURL(u string) bool { } return true } - -func arePointerValuesEqual[V comparable](a *V, b *V) bool { - if a == nil && b == nil { - return true - } - if a != nil && b != nil { - return *a == *b - } - return false -}