-
Notifications
You must be signed in to change notification settings - Fork 35
/
handler.go
120 lines (104 loc) · 2.91 KB
/
handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package hal
import (
"fmt"
"regexp"
"strings"
)
var (
// RespondRegexp is used to determine whether a received message should be processed as a response
respondRegexp = fmt.Sprintf(`^(?:@?(?:%s|%s)[:,]?)\s+(?:(.+))`, Config.Alias, Config.Name)
// RespondRegexpTemplate expands the RespondRegexp
respondRegexpTemplate = fmt.Sprintf(`^(?:@?(?:%s|%s)[:,]?)\s+(?:${1})`, Config.Alias, Config.Name)
)
// handler is an interface for objects to implement in order to respond to messages.
type handler interface {
Handle(res *Response) error
}
// Handlers is a map of registered handlers
var Handlers = map[string]handler{}
func handlerMatch(r *regexp.Regexp, text string) bool {
if !r.MatchString(text) {
return false
}
return true
}
func handlerRegexp(method, pattern string) *regexp.Regexp {
if method == RESPOND {
return regexp.MustCompile(strings.Replace(respondRegexpTemplate, "${1}", pattern, 1))
}
return regexp.MustCompile(pattern)
}
// NewHandler checks whether h implements the handler interface, wrapping it in a FullHandler
func NewHandler(h interface{}) (handler, error) {
switch v := h.(type) {
case fullHandler:
return &FullHandler{handler: v}, nil
case handler:
return v, nil
default:
return nil, fmt.Errorf("%v does not implement the handler interface", v)
}
}
// Handler type
type Handler struct {
Method string
Pattern string
Usage string
Run func(res *Response) error
}
// Handle func
func (h *Handler) Handle(res *Response) error {
switch {
// handle the response without matching
case h.Pattern == "":
return h.Run(res)
// handle the response after finding matches
case h.match(res):
res.Match = h.regexp().FindAllStringSubmatch(res.Message.Text, -1)[0]
return h.Run(res)
// if we don't find a match, return
default:
return nil
}
}
func (h *Handler) regexp() *regexp.Regexp {
return handlerRegexp(h.Method, h.Pattern)
}
// Match func
func (h *Handler) match(res *Response) bool {
return handlerMatch(h.regexp(), res.Message.Text)
}
// fullHandler is an interface for objects that wish to supply their own define methods
type fullHandler interface {
Run(*Response) error
Usage() string
Pattern() string
Method() string
}
// FullHandler declares common functions shared by all handlers
type FullHandler struct {
handler fullHandler
}
// Regexp func
func (h *FullHandler) Regexp() *regexp.Regexp {
return handlerRegexp(h.handler.Method(), h.handler.Pattern())
}
// Match func
func (h *FullHandler) Match(res *Response) bool {
return handlerMatch(h.Regexp(), res.Message.Text)
}
// Handle func
func (h *FullHandler) Handle(res *Response) error {
switch {
// handle the response without matching
case h.handler.Pattern() == "":
return h.handler.Run(res)
// handle the response after finding matches
case h.Match(res):
res.Match = h.Regexp().FindAllStringSubmatch(res.Text(), -1)[0]
return h.handler.Run(res)
// if we don't find a match, return
default:
return nil
}
}