/
provider.go
59 lines (51 loc) · 1.48 KB
/
provider.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
package core
import (
"errors"
"reflect"
)
// TryTemplate creates a new account template for the given provider and returns that --
// if provider implements `Accountant` interface. Otherwise, simply `nil` is returned
func TryTemplate(p Provider) Account {
if acct, ok := p.(Accountant); ok {
return acct.NewTemplate()
}
return nil
}
// Providers represents an array of providers with some utility functions
type Providers []Provider
var globalProviders = Providers{}
// RegisterProvider is not thread-safe!!!!
func RegisterProvider(p Provider) error {
duplicate := globalProviders.GetProvider(p.Name())
if duplicate != nil {
return errors.New("Duplicate " + p.Name() + "!")
}
globalProviders = append(globalProviders, p)
return nil
}
// RegisteredProviders returns a list of registered providers
func RegisteredProviders() Providers {
l := len(globalProviders)
ps := make([]Provider, l)
for i, p := range globalProviders {
p2v := reflect.New(reflect.Indirect(reflect.ValueOf(p)).Type())
ps[i] = p2v.Interface().(Provider)
}
return ps
}
// GetProvider returns the provider for the given string, or `nil` if there was none.
func (ps Providers) GetProvider(name string) Provider {
return ps.FindProvider(func(p Provider) bool {
return p.Name() == name
})
}
// FindProvider searches providers (in order).
// Returns the first to satisfy the predicate
func (ps Providers) FindProvider(f func(Provider) bool) Provider {
for _, p := range ps {
if f(p) {
return p
}
}
return nil
}