mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-03-17 21:32:56 +01:00
use generic functions for dealing with lists.
This commit is contained in:
parent
c4d52e516f
commit
f98f54d3be
11
event_aux.go
11
event_aux.go
@ -7,9 +7,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
type Tags []StringList
|
||||
type Tags [][]string
|
||||
|
||||
func (t *Tags) Scan(src interface{}) error {
|
||||
var jtags []byte = make([]byte, 0)
|
||||
@ -27,7 +28,7 @@ func (t *Tags) Scan(src interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tags Tags) ContainsAny(tagName string, values StringList) bool {
|
||||
func (tags Tags) ContainsAny(tagName string, values []string) bool {
|
||||
for _, tag := range tags {
|
||||
if len(tag) < 2 {
|
||||
continue
|
||||
@ -37,7 +38,7 @@ func (tags Tags) ContainsAny(tagName string, values StringList) bool {
|
||||
continue
|
||||
}
|
||||
|
||||
if values.Contains(tag[1]) {
|
||||
if slices.Contains(values, tag[1]) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -146,14 +147,14 @@ func fastjsonArrayToTags(v *fastjson.Value) (Tags, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sll := make([]StringList, len(arr))
|
||||
sll := make([][]string, len(arr))
|
||||
for i, v := range arr {
|
||||
subarr, err := v.Array()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sl := make(StringList, len(subarr))
|
||||
sl := make([]string, len(subarr))
|
||||
for j, subv := range subarr {
|
||||
sb, err := subv.StringBytes()
|
||||
if err != nil {
|
||||
|
24
filter.go
24
filter.go
@ -2,21 +2,23 @@ package nostr
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
type Filters []Filter
|
||||
|
||||
type Filter struct {
|
||||
IDs StringList
|
||||
Kinds IntList
|
||||
Authors StringList
|
||||
IDs []string
|
||||
Kinds []int
|
||||
Authors []string
|
||||
Tags TagMap
|
||||
Since *time.Time
|
||||
Until *time.Time
|
||||
Limit int
|
||||
}
|
||||
|
||||
type TagMap map[string]StringList
|
||||
type TagMap map[string][]string
|
||||
|
||||
func (eff Filters) Match(event *Event) bool {
|
||||
for _, filter := range eff {
|
||||
@ -32,15 +34,15 @@ func (ef Filter) Matches(event *Event) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if ef.IDs != nil && !ef.IDs.ContainsPrefixOf(event.ID) {
|
||||
if ef.IDs != nil && !ContainsPrefixOf(ef.IDs, event.ID) {
|
||||
return false
|
||||
}
|
||||
|
||||
if ef.Kinds != nil && !ef.Kinds.Contains(event.Kind) {
|
||||
if ef.Kinds != nil && !slices.Contains(ef.Kinds, event.Kind) {
|
||||
return false
|
||||
}
|
||||
|
||||
if ef.Authors != nil && !ef.Authors.ContainsPrefixOf(event.PubKey) {
|
||||
if ef.Authors != nil && !ContainsPrefixOf(ef.Authors, event.PubKey) {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -62,15 +64,15 @@ func (ef Filter) Matches(event *Event) bool {
|
||||
}
|
||||
|
||||
func FilterEqual(a Filter, b Filter) bool {
|
||||
if !a.Kinds.Equals(b.Kinds) {
|
||||
if !Similar(a.Kinds, b.Kinds) {
|
||||
return false
|
||||
}
|
||||
|
||||
if !a.IDs.Equals(b.IDs) {
|
||||
if !Similar(a.IDs, b.IDs) {
|
||||
return false
|
||||
}
|
||||
|
||||
if !a.Authors.Equals(b.Authors) {
|
||||
if !Similar(a.Authors, b.Authors) {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -82,7 +84,7 @@ func FilterEqual(a Filter, b Filter) bool {
|
||||
if bv, ok := b.Tags[f]; !ok {
|
||||
return false
|
||||
} else {
|
||||
if !av.Equals(bv) {
|
||||
if !Similar(av, bv) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ func (f Filter) MarshalJSON() ([]byte, error) {
|
||||
return o.MarshalTo(nil), nil
|
||||
}
|
||||
|
||||
func stringListToFastjsonArray(arena *fastjson.Arena, sl StringList) *fastjson.Value {
|
||||
func stringListToFastjsonArray(arena *fastjson.Arena, sl []string) *fastjson.Value {
|
||||
arr := arena.NewArray()
|
||||
for i, v := range sl {
|
||||
arr.SetArrayItem(i, arena.NewString(v))
|
||||
@ -117,7 +117,7 @@ func stringListToFastjsonArray(arena *fastjson.Arena, sl StringList) *fastjson.V
|
||||
return arr
|
||||
}
|
||||
|
||||
func intListToFastjsonArray(arena *fastjson.Arena, il IntList) *fastjson.Value {
|
||||
func intListToFastjsonArray(arena *fastjson.Arena, il []int) *fastjson.Value {
|
||||
arr := arena.NewArray()
|
||||
for i, v := range il {
|
||||
arr.SetArrayItem(i, arena.NewNumberInt(v))
|
||||
@ -125,13 +125,13 @@ func intListToFastjsonArray(arena *fastjson.Arena, il IntList) *fastjson.Value {
|
||||
return arr
|
||||
}
|
||||
|
||||
func fastjsonArrayToStringList(v *fastjson.Value) (StringList, error) {
|
||||
func fastjsonArrayToStringList(v *fastjson.Value) ([]string, error) {
|
||||
arr, err := v.Array()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sl := make(StringList, len(arr))
|
||||
sl := make([]string, len(arr))
|
||||
for i, v := range arr {
|
||||
sb, err := v.StringBytes()
|
||||
if err != nil {
|
||||
@ -143,13 +143,13 @@ func fastjsonArrayToStringList(v *fastjson.Value) (StringList, error) {
|
||||
return sl, nil
|
||||
}
|
||||
|
||||
func fastjsonArrayToIntList(v *fastjson.Value) (IntList, error) {
|
||||
func fastjsonArrayToIntList(v *fastjson.Value) ([]int, error) {
|
||||
arr, err := v.Array()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
il := make(IntList, len(arr))
|
||||
il := make([]int, len(arr))
|
||||
for i, v := range arr {
|
||||
il[i], err = v.Int()
|
||||
if err != nil {
|
||||
|
@ -4,6 +4,8 @@ import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
func TestFilterUnmarshal(t *testing.T) {
|
||||
@ -16,7 +18,7 @@ func TestFilterUnmarshal(t *testing.T) {
|
||||
|
||||
if f.Since == nil || f.Since.Format("2006-01-02") != "2022-02-07" ||
|
||||
f.Until != nil ||
|
||||
f.Tags == nil || len(f.Tags) != 2 || !f.Tags["something"].Contains("bab") {
|
||||
f.Tags == nil || len(f.Tags) != 2 || !slices.Contains(f.Tags["something"], "bab") {
|
||||
t.Error("failed to parse filter correctly")
|
||||
}
|
||||
}
|
||||
@ -25,7 +27,7 @@ func TestFilterMarshal(t *testing.T) {
|
||||
tm := time.Unix(12345678, 0)
|
||||
|
||||
filterj, err := json.Marshal(Filter{
|
||||
Kinds: IntList{1, 2, 4},
|
||||
Kinds: []int{1, 2, 4},
|
||||
Tags: TagMap{"fruit": {"banana", "mango"}},
|
||||
Until: &tm,
|
||||
})
|
||||
@ -40,20 +42,20 @@ func TestFilterMarshal(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFilterMatching(t *testing.T) {
|
||||
if (Filter{Kinds: IntList{4, 5}}).Matches(&Event{Kind: 6}) {
|
||||
if (Filter{Kinds: []int{4, 5}}).Matches(&Event{Kind: 6}) {
|
||||
t.Error("matched event that shouldn't have matched")
|
||||
}
|
||||
|
||||
if !(Filter{Kinds: IntList{4, 5}}).Matches(&Event{Kind: 4}) {
|
||||
if !(Filter{Kinds: []int{4, 5}}).Matches(&Event{Kind: 4}) {
|
||||
t.Error("failed to match event by kind")
|
||||
}
|
||||
|
||||
if !(Filter{
|
||||
Kinds: IntList{4, 5},
|
||||
Kinds: []int{4, 5},
|
||||
Tags: TagMap{
|
||||
"p": {"ooo"},
|
||||
},
|
||||
IDs: StringList{"prefix"},
|
||||
IDs: []string{"prefix"},
|
||||
}).Matches(&Event{
|
||||
Kind: 4,
|
||||
Tags: Tags{{"p", "ooo", ",x,x,"}, {"m", "yywyw", "xxx"}},
|
||||
@ -65,15 +67,15 @@ func TestFilterMatching(t *testing.T) {
|
||||
|
||||
func TestFilterEquality(t *testing.T) {
|
||||
if !FilterEqual(
|
||||
Filter{Kinds: IntList{4, 5}},
|
||||
Filter{Kinds: IntList{4, 5}},
|
||||
Filter{Kinds: []int{4, 5}},
|
||||
Filter{Kinds: []int{4, 5}},
|
||||
) {
|
||||
t.Error("kinds filters should be equal")
|
||||
}
|
||||
|
||||
if !FilterEqual(
|
||||
Filter{Kinds: IntList{4, 5}, Tags: TagMap{"letter": {"a", "b"}}},
|
||||
Filter{Kinds: IntList{4, 5}, Tags: TagMap{"letter": {"b", "a"}}},
|
||||
Filter{Kinds: []int{4, 5}, Tags: TagMap{"letter": {"a", "b"}}},
|
||||
Filter{Kinds: []int{4, 5}, Tags: TagMap{"letter": {"b", "a"}}},
|
||||
) {
|
||||
t.Error("kind+tags filters should be equal")
|
||||
}
|
||||
@ -81,24 +83,24 @@ func TestFilterEquality(t *testing.T) {
|
||||
tm := time.Now()
|
||||
if !FilterEqual(
|
||||
Filter{
|
||||
Kinds: IntList{4, 5},
|
||||
Kinds: []int{4, 5},
|
||||
Tags: TagMap{"letter": {"a", "b"}, "fruit": {"banana"}},
|
||||
Since: &tm,
|
||||
IDs: StringList{"aaaa", "bbbb"},
|
||||
IDs: []string{"aaaa", "bbbb"},
|
||||
},
|
||||
Filter{
|
||||
Kinds: IntList{5, 4},
|
||||
Kinds: []int{5, 4},
|
||||
Tags: TagMap{"letter": {"a", "b"}, "fruit": {"banana"}},
|
||||
Since: &tm,
|
||||
IDs: StringList{"aaaa", "bbbb"},
|
||||
IDs: []string{"aaaa", "bbbb"},
|
||||
},
|
||||
) {
|
||||
t.Error("kind+2tags+since+ids filters should be equal")
|
||||
}
|
||||
|
||||
if FilterEqual(
|
||||
Filter{Kinds: IntList{1, 4, 5}},
|
||||
Filter{Kinds: IntList{4, 5, 6}},
|
||||
Filter{Kinds: []int{1, 4, 5}},
|
||||
Filter{Kinds: []int{4, 5, 6}},
|
||||
) {
|
||||
t.Error("kinds filters shouldn't be equal")
|
||||
}
|
||||
|
1
go.mod
1
go.mod
@ -10,6 +10,7 @@ require (
|
||||
github.com/tyler-smith/go-bip32 v1.0.0
|
||||
github.com/tyler-smith/go-bip39 v1.1.0
|
||||
github.com/valyala/fastjson v1.6.3
|
||||
golang.org/x/exp v0.0.0-20221106115401-f9659909a136
|
||||
)
|
||||
|
||||
require (
|
||||
|
2
go.sum
2
go.sum
@ -34,6 +34,8 @@ golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnf
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20221106115401-f9659909a136 h1:Fq7F/w7MAa1KJ5bt2aJ62ihqp9HDcRuyILskkpIAurw=
|
||||
golang.org/x/exp v0.0.0-20221106115401-f9659909a136/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
48
helpers.go
48
helpers.go
@ -2,12 +2,11 @@ package nostr
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
type StringList []string
|
||||
type IntList []int
|
||||
|
||||
func (as StringList) Equals(bs StringList) bool {
|
||||
func Similar[E constraints.Ordered](as, bs []E) bool {
|
||||
if len(as) != len(bs) {
|
||||
return false
|
||||
}
|
||||
@ -28,37 +27,7 @@ func (as StringList) Equals(bs StringList) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (as IntList) Equals(bs IntList) 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
|
||||
}
|
||||
|
||||
func (haystack StringList) Contains(needle string) bool {
|
||||
for _, hay := range haystack {
|
||||
if hay == needle {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (haystack StringList) ContainsPrefixOf(needle string) bool {
|
||||
func ContainsPrefixOf(haystack []string, needle string) bool {
|
||||
for _, hay := range haystack {
|
||||
if strings.HasPrefix(needle, hay) {
|
||||
return true
|
||||
@ -66,12 +35,3 @@ func (haystack StringList) ContainsPrefixOf(needle string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (haystack IntList) Contains(needle int) bool {
|
||||
for _, hay := range haystack {
|
||||
if hay == needle {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user