From b4391985180f35e3c4ef7a34ab31ca29250c3149 Mon Sep 17 00:00:00 2001 From: Matt Goodall Date: Mon, 16 Jul 2012 12:02:05 +0100 Subject: [PATCH] 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. --- client.go | 10 ++++++---- src/xmpp/xmpp.go | 47 +++++++++++++++++++++++++++++++---------------- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/client.go b/client.go index 7daca71..752a983 100644 --- a/client.go +++ b/client.go @@ -28,10 +28,12 @@ func main() { // Filter messages into dedicated channel and start a goroutine to log them. _, messages := x.AddFilter( - func(v interface{}) bool { - _, ok := v.(*xmpp.Message) - return ok - }, + xmpp.MatcherFunc( + func(v interface{}) bool { + _, ok := v.(*xmpp.Message) + return ok + }, + ), ) go func() { for message := range messages { diff --git a/src/xmpp/xmpp.go b/src/xmpp/xmpp.go index c248d3e..d4a6653 100644 --- a/src/xmpp/xmpp.go +++ b/src/xmpp/xmpp.go @@ -71,7 +71,7 @@ func (fid FilterId) Error() string { 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. x.filterLock.Lock() @@ -84,7 +84,7 @@ func (x *XMPP) AddFilter(fn FilterFn) (FilterId, chan interface{}) { // Insert at head of filters list. filters := make([]filter, len(x.filters)+1) - filters[0] = filter{id, fn, ch} + filters[0] = filter{id, m, ch} copy(filters[1:], x.filters) x.filters = filters @@ -119,24 +119,39 @@ func (x *XMPP) RemoveFilter(id FilterId) error { return id } -func IqResult(id string) FilterFn { - return func(v interface{}) bool { - iq, ok := v.(*Iq) - if !ok { - return false - } - if iq.Id != id { - return false - } - return true - } +func IqResult(id string) Matcher { + return MatcherFunc( + func(v interface{}) bool { + iq, ok := v.(*Iq) + if !ok { + return false + } + if iq.Id != id { + return false + } + 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 { id FilterId - fn FilterFn + m Matcher ch chan interface{} } @@ -178,7 +193,7 @@ func (x *XMPP) receiver() { filtered := false for _, filter := range x.filters { - if filter.fn(v) { + if filter.m.Match(v) { filter.ch <- v filtered = true }