57 lines
1.2 KiB
Go
57 lines
1.2 KiB
Go
package module
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"sync"
|
|
)
|
|
|
|
// Registry holds all known modules keyed by Meta.ID.
|
|
type Registry struct {
|
|
mu sync.RWMutex
|
|
modules map[string]Module
|
|
}
|
|
|
|
// NewRegistry returns an empty registry.
|
|
func NewRegistry() *Registry {
|
|
return &Registry{modules: make(map[string]Module)}
|
|
}
|
|
|
|
// Register adds a module. Returns an error if the ID is already present
|
|
// or empty. Safe for concurrent use.
|
|
func (r *Registry) Register(m Module) error {
|
|
id := m.Meta().ID
|
|
if id == "" {
|
|
return fmt.Errorf("module has empty ID")
|
|
}
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
if _, dup := r.modules[id]; dup {
|
|
return fmt.Errorf("module %q already registered", id)
|
|
}
|
|
r.modules[id] = m
|
|
return nil
|
|
}
|
|
|
|
// Get returns the module with the given ID, or (nil, false) if absent.
|
|
func (r *Registry) Get(id string) (Module, bool) {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
m, ok := r.modules[id]
|
|
return m, ok
|
|
}
|
|
|
|
// All returns all registered modules sorted by ID for determinism.
|
|
func (r *Registry) All() []Module {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
out := make([]Module, 0, len(r.modules))
|
|
for _, m := range r.modules {
|
|
out = append(out, m)
|
|
}
|
|
sort.Slice(out, func(i, j int) bool {
|
|
return out[i].Meta().ID < out[j].Meta().ID
|
|
})
|
|
return out
|
|
}
|