1package registry
2
3import (
4	"fmt"
5)
6
7type FactoryAlreadyRegisteredError struct {
8	factoryType string
9	factoryName string
10}
11
12func NewFactoryAlreadyRegisteredError(factoryType string, factoryName string) *FactoryAlreadyRegisteredError {
13	return &FactoryAlreadyRegisteredError{
14		factoryType: factoryType,
15		factoryName: factoryName,
16	}
17}
18
19func (e *FactoryAlreadyRegisteredError) Error() string {
20	return fmt.Sprintf("factory for %s %q already registered", e.factoryType, e.factoryName)
21}
22
23func (e *FactoryAlreadyRegisteredError) Is(err error) bool {
24	eerr, ok := err.(*FactoryAlreadyRegisteredError)
25	if !ok {
26		return false
27	}
28
29	return eerr.factoryName == e.factoryName
30}
31
32type FactoryNotRegisteredError struct {
33	factoryType string
34	factoryName string
35}
36
37func NewFactoryNotRegisteredError(factoryType string, factoryName string) *FactoryNotRegisteredError {
38	return &FactoryNotRegisteredError{
39		factoryType: factoryType,
40		factoryName: factoryName,
41	}
42}
43
44func (e *FactoryNotRegisteredError) Error() string {
45	return fmt.Sprintf("factory for %s %q is not registered", e.factoryType, e.factoryName)
46}
47
48func (e *FactoryNotRegisteredError) Is(err error) bool {
49	eerr, ok := err.(*FactoryNotRegisteredError)
50	if !ok {
51		return false
52	}
53
54	return eerr.factoryName == e.factoryName
55}
56
57type Registry interface {
58	Register(factoryName string, factory interface{}) error
59	Get(factoryName string) (interface{}, error)
60}
61
62type factoryRegistry struct {
63	factoryType string
64	store       map[string]interface{}
65}
66
67func (r factoryRegistry) Register(factoryName string, factory interface{}) error {
68	_, ok := r.store[factoryName]
69	if ok {
70		return NewFactoryAlreadyRegisteredError(r.factoryType, factoryName)
71	}
72
73	r.store[factoryName] = factory
74
75	return nil
76}
77
78func (r factoryRegistry) Get(factoryName string) (interface{}, error) {
79	factory, ok := r.store[factoryName]
80	if !ok {
81		return nil, NewFactoryNotRegisteredError(r.factoryType, factoryName)
82	}
83
84	return factory, nil
85}
86
87func New(factoryType string) Registry {
88	return &factoryRegistry{
89		factoryType: factoryType,
90		store:       make(map[string]interface{}),
91	}
92}
93