diff --git a/event_aux.go b/event_aux.go index 2b03465..29cc6cd 100644 --- a/event_aux.go +++ b/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 { diff --git a/filter.go b/filter.go index e4c196a..8bc42a6 100644 --- a/filter.go +++ b/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 } } diff --git a/filter_aux.go b/filter_aux.go index 5320d88..2f755ea 100644 --- a/filter_aux.go +++ b/filter_aux.go @@ -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 { diff --git a/filter_test.go b/filter_test.go index 0aed216..26c2b54 100644 --- a/filter_test.go +++ b/filter_test.go @@ -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") } diff --git a/go.mod b/go.mod index d07c8c0..d753823 100644 --- a/go.mod +++ b/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 ( diff --git a/go.sum b/go.sum index 9996a75..08af53f 100644 --- a/go.sum +++ b/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= diff --git a/helpers.go b/helpers.go index 2637fdd..d28d4c7 100644 --- a/helpers.go +++ b/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 -}