forked from SakoDroid/telego
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tree.go
116 lines (106 loc) 路 2.38 KB
/
tree.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
package parser
import (
"strings"
objs "github.com/fulviodenza/telego/v2/objects"
)
// TreeNode is a special tree element containing handlers.
type TreeNode struct {
father *TreeNode
right, left *TreeNode
data *handler
}
// handlerTree is a special binary tree for storing handlers. Right node hase a value that does not match the it's father regex and the left node matches it's father regex.
type handlerTree struct {
root *TreeNode
}
// AddHandler adds a new handler to the tree.
func (tr *handlerTree) AddHandler(hdl *handler) {
tn := TreeNode{data: hdl}
tr.addNode(&tn)
}
// GetHandler gets the proper handler for the given text.
func (tr *handlerTree) GetHandler(msg *objs.Message) *handler {
msgText := msg.Text
if msg.Caption != "" {
msgText = msg.Caption
}
tn := tr.findTheNodeRegex(msgText, msg.Chat.Type)
if tn != nil {
return tn.data
}
return nil
}
func (tr *handlerTree) findTheNodeRegex(text, chatType string) *TreeNode {
node := tr.root
for {
if node == nil {
break
}
if node.data.regex.Match([]byte(text)) {
if node.left != nil {
node = node.left
} else {
break
}
} else {
if node.right != nil {
node = node.right
} else {
node = node.father
break
}
}
}
return tr.checkForChatTypes(node, chatType, text)
}
func (tr *handlerTree) checkForChatTypes(currentNode *TreeNode, chatType, text string) *TreeNode {
for {
if currentNode == nil {
break
}
if (strings.Contains(currentNode.data.chatType, chatType) || strings.Contains(currentNode.data.chatType, "all")) && currentNode.data.regex.Match([]byte(text)) {
break
} else {
currentNode = currentNode.father
}
}
return currentNode
}
// Finds the perfect location for this handler.
func (tr *handlerTree) addNode(tn *TreeNode) {
var fatherNode *TreeNode
node := tr.root
dir := 0
for {
//this is the spot
if node == nil {
if fatherNode != nil {
tn.father = fatherNode
if dir == 0 {
fatherNode.left = tn
} else {
fatherNode.right = tn
}
} else {
//Root node
tr.root = tn
}
break
} else {
if tr.checkRegex(node, tn) {
dir = 0
fatherNode = node
node = fatherNode.left
} else {
dir = 1
fatherNode = node
node = fatherNode.right
}
}
}
}
func (tr *handlerTree) checkRegex(father, child *TreeNode) bool {
return father.data.regex.Match(
[]byte(child.data.regex.String()),
)
}