jx/internal/source/types.go
Matthew Rich 976f654c60
Some checks failed
Lint / golangci-lint (push) Failing after 9m47s
Declarative Tests / test (push) Failing after 10s
handle numeric user ids
2024-04-17 17:07:12 -07:00

93 lines
2.0 KiB
Go

// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
package source
import (
"errors"
"fmt"
"net/url"
"strings"
"path/filepath"
)
var (
ErrUnknownSourceType = errors.New("Unknown source type")
SourceTypes *Types = NewTypes()
)
type TypeName string //`json:"type"`
type TypeFactory func(*url.URL) DocSource
type Types struct {
registry map[string]TypeFactory
}
func NewTypes() *Types {
return &Types{registry: make(map[string]TypeFactory)}
}
func (t *Types) Register(names []string, factory TypeFactory) {
for _,name := range names {
t.registry[name] = factory
}
}
func (t *Types) FromExtension(path string) (TypeFactory, error) {
elements := strings.Split(path, ".")
numberOfElements := len(elements)
if numberOfElements > 2 {
if src := t.Get(strings.Join(elements[numberOfElements - 2: numberOfElements - 1], ".")); src != nil {
return src, nil
}
}
if src := t.Get(elements[numberOfElements - 1]); src != nil {
return src, nil
}
return nil, fmt.Errorf("%w: %s", ErrUnknownSourceType, path)
}
func (t *Types) New(uri string) (DocSource, error) {
u, e := url.Parse(uri)
if u == nil || e != nil {
return nil, fmt.Errorf("%w: %s", ErrUnknownSourceType, e)
}
if u.Scheme == "" {
u.Scheme = "file"
}
path := filepath.Join(u.Hostname(), u.Path)
if d, lookupErr := t.FromExtension(path); d != nil {
return d(u), lookupErr
}
if r, ok := t.registry[u.Scheme]; ok {
return r(u), nil
}
return nil, fmt.Errorf("%w: %s", ErrUnknownSourceType, u.Scheme)
}
func (t *Types) Has(typename string) bool {
if _, ok := t.registry[typename]; ok {
return true
}
return false
}
func (t *Types) Get(typename string) TypeFactory {
if d, ok := t.registry[typename]; ok {
return d
}
return nil
}
func (n *TypeName) UnmarshalJSON(b []byte) error {
SourceTypeName := strings.Trim(string(b), "\"")
if SourceTypes.Has(SourceTypeName) {
*n = TypeName(SourceTypeName)
return nil
}
return fmt.Errorf("%w: %s", ErrUnknownSourceType, SourceTypeName)
}