master
go 108 lines 2.33 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package functions
4
5 import "strings"
6
7 func (m *Manager) Register(name string, fn func(Function)) {
8 if fn == nil {
9 m.Warningf("not registering '%s': nil function", name)
10 return
11 }
12
13 m.mux.Lock()
14 defer m.mux.Unlock()
15
16 fs, ok := m.functionRegistry[name]
17 if !ok {
18 m.Debugf("registering function '%s' (direct)", name)
19 fs = &functionSet{prefixes: make(map[string]func(Function))}
20 m.functionRegistry[name] = fs
21 } else {
22 if fs.direct != nil {
23 m.Warningf("re-registering direct function '%s'", name)
24 } else {
25 m.Debugf("registering function '%s' (direct)", name)
26 }
27 }
28
29 fs.direct = fn
30 }
31
32 func (m *Manager) Unregister(name string) {
33 m.mux.Lock()
34 defer m.mux.Unlock()
35
36 if _, ok := m.functionRegistry[name]; ok {
37 delete(m.functionRegistry, name)
38 m.Debugf("unregistering function '%s'", name)
39 }
40 }
41
42 func (m *Manager) RegisterPrefix(name, prefix string, fn func(Function)) {
43 if fn == nil {
44 m.Warningf("not registering '%s' with prefix '%s': nil function", name, prefix)
45 return
46 }
47 if prefix == "" {
48 m.Warningf("not registering '%s': empty prefix", name)
49 return
50 }
51
52 m.mux.Lock()
53 defer m.mux.Unlock()
54
55 fs := m.functionRegistry[name]
56 if fs == nil {
57 fs = &functionSet{prefixes: make(map[string]func(Function))}
58 m.functionRegistry[name] = fs
59 }
60
61 if _, exists := fs.prefixes[prefix]; exists {
62 m.Warningf("re-registering function '%s' with prefix '%s'", name, prefix)
63 fs.prefixes[prefix] = fn
64 return
65 }
66
67 for existing := range fs.prefixes {
68 if prefixesOverlap(existing, prefix) {
69 m.Errorf(
70 "not registering function '%s' with prefix '%s': overlaps with existing prefix '%s'",
71 name,
72 prefix,
73 existing,
74 )
75 return
76 }
77 }
78
79 m.Debugf("registering function '%s' with prefix '%s'", name, prefix)
80 fs.prefixes[prefix] = fn
81 }
82
83 func prefixesOverlap(a, b string) bool {
84 if a == "" || b == "" {
85 return false
86 }
87
88 return strings.HasPrefix(a, b) || strings.HasPrefix(b, a)
89 }
90
91 func (m *Manager) UnregisterPrefix(name, prefix string) {
92 m.mux.Lock()
93 defer m.mux.Unlock()
94
95 fs, ok := m.functionRegistry[name]
96 if !ok || fs.prefixes == nil {
97 return
98 }
99
100 if _, exists := fs.prefixes[prefix]; exists {
101 m.Debugf("unregistering function '%s' with prefix '%s'", name, prefix)
102 delete(fs.prefixes, prefix)
103 }
104
105 if fs.direct == nil && len(fs.prefixes) == 0 {
106 delete(m.functionRegistry, name)
107 }
108 }