package storage import ( "context" "sync" ) type OpenConfig map[string]string type Opener func(context.Context, OpenConfig) (Backend, error) type Registry struct { mu sync.RWMutex openers map[string]Opener } func NewRegistry() *Registry { return &Registry{openers: make(map[string]Opener)} } func (r *Registry) Register(name string, opener Opener) error { if name == "" || opener == nil { return NewError(OpRegisterBackend, name, "", ErrInvalidPath, nil) } r.mu.Lock() defer r.mu.Unlock() if _, exists := r.openers[name]; exists { return NewError(OpRegisterBackend, name, "", ErrAlreadyExist, nil) } r.openers[name] = opener return nil } func (r *Registry) Open(ctx context.Context, name string, cfg OpenConfig) (Backend, error) { r.mu.RLock() opener, ok := r.openers[name] r.mu.RUnlock() if !ok { return nil, NewError(OpOpenBackend, name, "", ErrUnsupported, nil) } backend, err := opener(ctx, cfg) if err != nil { return nil, err } return backend, nil }