Files
restic/internal/backend/location/registry.go
T

107 lines
3.8 KiB
Go

package location
import (
"context"
"net/http"
"github.com/restic/restic/internal/backend"
"github.com/restic/restic/internal/backend/limiter"
)
type Registry struct {
factories map[string]Factory
}
func NewRegistry() *Registry {
return &Registry{
factories: make(map[string]Factory),
}
}
func (r *Registry) Register(factory Factory) {
if r.factories[factory.Scheme()] != nil {
panic("duplicate backend")
}
r.factories[factory.Scheme()] = factory
}
func (r *Registry) Lookup(scheme string) Factory {
return r.factories[scheme]
}
type Factory interface {
Scheme() string
ParseConfig(s string) (any, error)
StripPassword(s string) string
Create(ctx context.Context, cfg any, rt http.RoundTripper, lim limiter.Limiter, errorLog func(string, ...any)) (backend.Backend, error)
Open(ctx context.Context, cfg any, rt http.RoundTripper, lim limiter.Limiter, errorLog func(string, ...any)) (backend.Backend, error)
}
type genericBackendFactory[C any, T backend.Backend] struct {
scheme string
parseConfigFn func(s string) (*C, error)
stripPasswordFn func(s string) string
createFn func(ctx context.Context, cfg C, rt http.RoundTripper, lim limiter.Limiter, errorLog func(string, ...any)) (T, error)
openFn func(ctx context.Context, cfg C, rt http.RoundTripper, lim limiter.Limiter, errorLog func(string, ...any)) (T, error)
}
func (f *genericBackendFactory[C, T]) Scheme() string {
return f.scheme
}
func (f *genericBackendFactory[C, T]) ParseConfig(s string) (any, error) {
return f.parseConfigFn(s)
}
func (f *genericBackendFactory[C, T]) StripPassword(s string) string {
if f.stripPasswordFn != nil {
return f.stripPasswordFn(s)
}
return s
}
func (f *genericBackendFactory[C, T]) Create(ctx context.Context, cfg any, rt http.RoundTripper, lim limiter.Limiter, errorLog func(string, ...any)) (backend.Backend, error) {
return f.createFn(ctx, *cfg.(*C), rt, lim, errorLog)
}
func (f *genericBackendFactory[C, T]) Open(ctx context.Context, cfg any, rt http.RoundTripper, lim limiter.Limiter, errorLog func(string, ...any)) (backend.Backend, error) {
return f.openFn(ctx, *cfg.(*C), rt, lim, errorLog)
}
func NewHTTPBackendFactory[C any, T backend.Backend](
scheme string,
parseConfigFn func(s string) (*C, error),
stripPasswordFn func(s string) string,
createFn func(ctx context.Context, cfg C, rt http.RoundTripper, errorLog func(string, ...any)) (T, error),
openFn func(ctx context.Context, cfg C, rt http.RoundTripper, errorLog func(string, ...any)) (T, error)) Factory {
return &genericBackendFactory[C, T]{
scheme: scheme,
parseConfigFn: parseConfigFn,
stripPasswordFn: stripPasswordFn,
createFn: func(ctx context.Context, cfg C, rt http.RoundTripper, _ limiter.Limiter, errorLog func(string, ...any)) (T, error) {
return createFn(ctx, cfg, rt, errorLog)
},
openFn: func(ctx context.Context, cfg C, rt http.RoundTripper, _ limiter.Limiter, errorLog func(string, ...any)) (T, error) {
return openFn(ctx, cfg, rt, errorLog)
},
}
}
func NewLimitedBackendFactory[C any, T backend.Backend](
scheme string,
parseConfigFn func(s string) (*C, error),
stripPasswordFn func(s string) string,
createFn func(ctx context.Context, cfg C, lim limiter.Limiter, errorLog func(string, ...any)) (T, error),
openFn func(ctx context.Context, cfg C, lim limiter.Limiter, errorLog func(string, ...any)) (T, error)) Factory {
return &genericBackendFactory[C, T]{
scheme: scheme,
parseConfigFn: parseConfigFn,
stripPasswordFn: stripPasswordFn,
createFn: func(ctx context.Context, cfg C, _ http.RoundTripper, lim limiter.Limiter, errorLog func(string, ...any)) (T, error) {
return createFn(ctx, cfg, lim, errorLog)
},
openFn: func(ctx context.Context, cfg C, _ http.RoundTripper, lim limiter.Limiter, errorLog func(string, ...any)) (T, error) {
return openFn(ctx, cfg, lim, errorLog)
},
}
}