forked from chteufleur/go-xmpp
Convert FilterFn into the Matcher/MatcherFunc interface/adapter pair.
"Matcher" is a better name for how it's used. It also allows other types to implement the interface.
This commit is contained in:
parent
17d143cb2c
commit
b439198518
10
client.go
10
client.go
|
|
@ -28,10 +28,12 @@ func main() {
|
||||||
|
|
||||||
// Filter messages into dedicated channel and start a goroutine to log them.
|
// Filter messages into dedicated channel and start a goroutine to log them.
|
||||||
_, messages := x.AddFilter(
|
_, messages := x.AddFilter(
|
||||||
func(v interface{}) bool {
|
xmpp.MatcherFunc(
|
||||||
_, ok := v.(*xmpp.Message)
|
func(v interface{}) bool {
|
||||||
return ok
|
_, ok := v.(*xmpp.Message)
|
||||||
},
|
return ok
|
||||||
|
},
|
||||||
|
),
|
||||||
)
|
)
|
||||||
go func() {
|
go func() {
|
||||||
for message := range messages {
|
for message := range messages {
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ func (fid FilterId) Error() string {
|
||||||
return fmt.Sprintf("Invalid filter id: %d", fid)
|
return fmt.Sprintf("Invalid filter id: %d", fid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *XMPP) AddFilter(fn FilterFn) (FilterId, chan interface{}) {
|
func (x *XMPP) AddFilter(m Matcher) (FilterId, chan interface{}) {
|
||||||
|
|
||||||
// Protect against concurrent access.
|
// Protect against concurrent access.
|
||||||
x.filterLock.Lock()
|
x.filterLock.Lock()
|
||||||
|
|
@ -84,7 +84,7 @@ func (x *XMPP) AddFilter(fn FilterFn) (FilterId, chan interface{}) {
|
||||||
|
|
||||||
// Insert at head of filters list.
|
// Insert at head of filters list.
|
||||||
filters := make([]filter, len(x.filters)+1)
|
filters := make([]filter, len(x.filters)+1)
|
||||||
filters[0] = filter{id, fn, ch}
|
filters[0] = filter{id, m, ch}
|
||||||
copy(filters[1:], x.filters)
|
copy(filters[1:], x.filters)
|
||||||
x.filters = filters
|
x.filters = filters
|
||||||
|
|
||||||
|
|
@ -119,24 +119,39 @@ func (x *XMPP) RemoveFilter(id FilterId) error {
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
func IqResult(id string) FilterFn {
|
func IqResult(id string) Matcher {
|
||||||
return func(v interface{}) bool {
|
return MatcherFunc(
|
||||||
iq, ok := v.(*Iq)
|
func(v interface{}) bool {
|
||||||
if !ok {
|
iq, ok := v.(*Iq)
|
||||||
return false
|
if !ok {
|
||||||
}
|
return false
|
||||||
if iq.Id != id {
|
}
|
||||||
return false
|
if iq.Id != id {
|
||||||
}
|
return false
|
||||||
return true
|
}
|
||||||
}
|
return true
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
type FilterFn func(v interface{}) bool
|
// Interface used to test if a stanza matches some application-defined
|
||||||
|
// conditions.
|
||||||
|
type Matcher interface {
|
||||||
|
// Return true if the stanza, v, matches.
|
||||||
|
Match(v interface{}) (match bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adapter to allow a plain func to be used as a Matcher.
|
||||||
|
type MatcherFunc func(v interface{}) bool
|
||||||
|
|
||||||
|
// Implement Matcher by calling the adapted func.
|
||||||
|
func (fn MatcherFunc) Match(v interface{}) bool {
|
||||||
|
return fn(v)
|
||||||
|
}
|
||||||
|
|
||||||
type filter struct {
|
type filter struct {
|
||||||
id FilterId
|
id FilterId
|
||||||
fn FilterFn
|
m Matcher
|
||||||
ch chan interface{}
|
ch chan interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,7 +193,7 @@ func (x *XMPP) receiver() {
|
||||||
|
|
||||||
filtered := false
|
filtered := false
|
||||||
for _, filter := range x.filters {
|
for _, filter := range x.filters {
|
||||||
if filter.fn(v) {
|
if filter.m.Match(v) {
|
||||||
filter.ch <- v
|
filter.ch <- v
|
||||||
filtered = true
|
filtered = true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue