|
1 | 1 | package operations
|
2 | 2 |
|
3 |
| -import "errors" |
| 3 | +import ( |
| 4 | + "errors" |
| 5 | + "fmt" |
| 6 | +) |
| 7 | + |
| 8 | +var ErrOperationNotFound = errors.New("operation not found in registry") |
4 | 9 |
|
5 | 10 | // OperationRegistry is a store for operations that allows retrieval based on their definitions.
|
6 | 11 | type OperationRegistry struct {
|
7 |
| - ops []*Operation[any, any, any] |
| 12 | + ops map[string]*Operation[any, any, any] |
8 | 13 | }
|
9 | 14 |
|
10 | 15 | // NewOperationRegistry creates a new OperationRegistry with the provided untyped operations.
|
11 | 16 | func NewOperationRegistry(ops ...*Operation[any, any, any]) *OperationRegistry {
|
12 |
| - return &OperationRegistry{ |
13 |
| - ops: ops, |
| 17 | + reg := &OperationRegistry{ |
| 18 | + ops: make(map[string]*Operation[any, any, any]), |
| 19 | + } |
| 20 | + for _, op := range ops { |
| 21 | + key := generateRegistryKey(op.Def()) |
| 22 | + reg.ops[key] = op |
14 | 23 | }
|
| 24 | + |
| 25 | + return reg |
15 | 26 | }
|
16 | 27 |
|
17 | 28 | // Retrieve retrieves an operation from the store based on its definition.
|
18 | 29 | // It returns an error if the operation is not found.
|
19 | 30 | // The definition must match the operation's ID and version.
|
| 31 | +// Description of the definition is not used for retrieval, only ID and Version. |
| 32 | +// This allows for simplicity in retrieving operations with the same ID and version only without having to provide the description. |
| 33 | +// This is useful when definition has to be provided via manual input. |
20 | 34 | func (s OperationRegistry) Retrieve(def Definition) (*Operation[any, any, any], error) {
|
21 |
| - for _, op := range s.ops { |
22 |
| - if op.ID() == def.ID && op.Version() == def.Version.String() { |
23 |
| - return op, nil |
24 |
| - } |
| 35 | + key := generateRegistryKey(def) |
| 36 | + if op, ok := s.ops[key]; ok { |
| 37 | + return op, nil |
25 | 38 | }
|
26 | 39 |
|
27 |
| - return nil, errors.New("operation not found in registry") |
| 40 | + return nil, ErrOperationNotFound |
28 | 41 | }
|
29 | 42 |
|
30 | 43 | // RegisterOperation registers new operations in the registry.
|
31 | 44 | // To register operations with different input, output, and dependency types,
|
32 | 45 | // call RegisterOperation multiple times with different type parameters.
|
| 46 | +// If the same operation is registered multiple times, it will overwrite the previous one. |
33 | 47 | func RegisterOperation[D, I, O any](r *OperationRegistry, op ...*Operation[D, I, O]) {
|
34 | 48 | for _, o := range op {
|
35 |
| - r.ops = append(r.ops, o.AsUntyped()) |
| 49 | + key := generateRegistryKey(o.Def()) |
| 50 | + r.ops[key] = o.AsUntyped() |
36 | 51 | }
|
37 | 52 | }
|
| 53 | + |
| 54 | +// generateRegistryKey creates a unique key for the operation registry based on the operation's ID and version. |
| 55 | +// This key is used to store and retrieve operations in the registry. |
| 56 | +func generateRegistryKey(def Definition) string { |
| 57 | + return fmt.Sprintf("%s:%s", def.ID, def.Version) |
| 58 | +} |
0 commit comments