Files
goget/internal/archive/registry.go
T

88 lines
2.0 KiB
Go

//go:build linux || freebsd
// +build linux freebsd
package archive
import (
"fmt"
"io"
"strings"
"sync"
)
type registry struct {
mu sync.RWMutex
extractors map[string]Extractor
}
var globalRegistry = &registry{extractors: make(map[string]Extractor)}
func Register(e Extractor) error {
globalRegistry.mu.Lock()
defer globalRegistry.mu.Unlock()
name := strings.ToLower(e.Name())
if name == "" {
return fmt.Errorf("extractor name cannot be empty")
}
if _, exists := globalRegistry.extractors[name]; exists {
return fmt.Errorf("extractor already registered: %s", name)
}
globalRegistry.extractors[name] = e
return nil
}
func Get(format string) (Extractor, error) {
globalRegistry.mu.RLock()
defer globalRegistry.mu.RUnlock()
e, exists := globalRegistry.extractors[strings.ToLower(format)]
if !exists {
return nil, fmt.Errorf("unsupported archive format: %s", format)
}
return e, nil
}
func GetByFilename(filename string) (Extractor, error) {
format := DetectArchiveFormat(filename)
if format == "" {
return nil, fmt.Errorf("unknown archive format for: %s", filename)
}
return Get(format)
}
func Extract(format string, src io.Reader, destDir string) error {
e, err := Get(format)
if err != nil {
return err
}
return e.Extract(src, destDir)
}
func ExtractByFilename(filename string, src io.Reader, destDir string) error {
e, err := GetByFilename(filename)
if err != nil {
return err
}
return e.Extract(src, destDir)
}
func AutoExtract(filename string, src io.Reader, destDir string) error {
return ExtractByFilename(filename, src, destDir)
}
func Supports(format string) bool {
globalRegistry.mu.RLock()
defer globalRegistry.mu.RUnlock()
_, exists := globalRegistry.extractors[strings.ToLower(format)]
return exists
}
func ListSupported() []string {
globalRegistry.mu.RLock()
defer globalRegistry.mu.RUnlock()
names := make([]string, 0, len(globalRegistry.extractors))
for name := range globalRegistry.extractors {
names = append(names, name)
}
return names
}