mirror of
https://github.com/crazybber/awesome-patterns.git
synced 2024-12-01 09:26:04 +03:00
100 lines
2.4 KiB
Go
100 lines
2.4 KiB
Go
|
package registry
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/google/uuid"
|
||
|
)
|
||
|
|
||
|
// IDNotFound is an error thrown when an id is not found in a Registry
|
||
|
type IDNotFound struct {
|
||
|
id string
|
||
|
}
|
||
|
|
||
|
func (e IDNotFound) Error() string {
|
||
|
return fmt.Sprintf("ID not found in registry: %s", e.id)
|
||
|
}
|
||
|
|
||
|
// NameAlreadyRegistered is an error thrown when a duplicate id is found durring registration
|
||
|
type NameAlreadyRegistered struct {
|
||
|
id string
|
||
|
}
|
||
|
|
||
|
func (e NameAlreadyRegistered) Error() string {
|
||
|
return fmt.Sprintf("Identifier was already in registry: %s", e.id)
|
||
|
}
|
||
|
|
||
|
// Registry acts a generic data registry
|
||
|
// Objects are registered with the underlying struct, which returns an ID string
|
||
|
// The ID string can then be used to retreive the object, or to remove it from the registry
|
||
|
type Registry interface {
|
||
|
|
||
|
// Deregister removes an item identified by the passed id
|
||
|
Deregister(id string) error
|
||
|
|
||
|
// Get retreives an item identified by the passed id from the registry
|
||
|
Get(id string) (interface{}, error)
|
||
|
|
||
|
// Prune removes nil entries from the registry
|
||
|
Prune()
|
||
|
|
||
|
// Register adds an item to the registry and returns an identifying string
|
||
|
Register(data interface{}) string
|
||
|
|
||
|
// RegisterName adds an item to the registry under the suppplied identifier and returns an identifying string
|
||
|
// Returns a NameAlreadyRegistered error if the identifier has already been registered
|
||
|
RegisterName(data interface{}, identifier string) error
|
||
|
}
|
||
|
|
||
|
type registry struct {
|
||
|
registry map[string]interface{}
|
||
|
}
|
||
|
|
||
|
func (reg *registry) Deregister(id string) error {
|
||
|
if _, ok := reg.registry[id]; ok {
|
||
|
delete(reg.registry, id)
|
||
|
return nil
|
||
|
}
|
||
|
return IDNotFound{id}
|
||
|
}
|
||
|
|
||
|
func (reg *registry) Get(id string) (interface{}, error) {
|
||
|
if data, ok := reg.registry[id]; ok {
|
||
|
return data, nil
|
||
|
}
|
||
|
return nil, IDNotFound{id}
|
||
|
}
|
||
|
|
||
|
func (reg *registry) Prune() {
|
||
|
for key, value := range reg.registry {
|
||
|
if value == nil {
|
||
|
delete(reg.registry, key)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (reg *registry) Register(data interface{}) string {
|
||
|
// Just in case the impossible happens and there is an id colision
|
||
|
for {
|
||
|
newUUID, _ := uuid.NewRandom()
|
||
|
id := newUUID.String()
|
||
|
if _, ok := reg.registry[id]; !ok {
|
||
|
reg.registry[id] = data
|
||
|
return id
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (reg *registry) RegisterName(data interface{}, identifier string) error {
|
||
|
if _, ok := reg.registry[identifier]; !ok {
|
||
|
reg.registry[identifier] = data
|
||
|
return nil
|
||
|
}
|
||
|
return NameAlreadyRegistered{identifier}
|
||
|
}
|
||
|
|
||
|
// New returns a new Registry interface
|
||
|
func New() Registry {
|
||
|
return ®istry{}
|
||
|
}
|