mirror of
https://github.com/wader/fq.git
synced 2024-12-26 15:02:28 +03:00
116 lines
2.2 KiB
Go
116 lines
2.2 KiB
Go
package registry
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"sort"
|
|
"sync"
|
|
|
|
"github.com/wader/fq/pkg/decode"
|
|
)
|
|
|
|
type Registry struct {
|
|
Groups map[string][]*decode.Format
|
|
resolveOnce sync.Once
|
|
resolved bool
|
|
}
|
|
|
|
func New() *Registry {
|
|
return &Registry{
|
|
Groups: map[string][]*decode.Format{},
|
|
resolveOnce: sync.Once{},
|
|
}
|
|
}
|
|
|
|
func (r *Registry) register(groupName string, format *decode.Format, single bool) *decode.Format { //nolint:unparam
|
|
if r.resolved {
|
|
// for now can't change after resolved
|
|
panic("registry already resolved")
|
|
}
|
|
|
|
formats, ok := r.Groups[groupName]
|
|
if ok {
|
|
if !single {
|
|
panic(fmt.Sprintf("%s: format already registered", groupName))
|
|
}
|
|
} else {
|
|
formats = []*decode.Format{}
|
|
}
|
|
|
|
r.Groups[groupName] = append(formats, format)
|
|
|
|
return format
|
|
}
|
|
|
|
func (r *Registry) MustRegister(format *decode.Format) *decode.Format {
|
|
r.register(format.Name, format, false)
|
|
for _, g := range format.Groups {
|
|
r.register(g, format, true)
|
|
}
|
|
r.register("all", format, true)
|
|
|
|
return format
|
|
}
|
|
|
|
func sortFormats(fs []*decode.Format) {
|
|
sort.Slice(fs, func(i, j int) bool {
|
|
if fs[i].ProbeOrder == fs[j].ProbeOrder {
|
|
return fs[i].Name < fs[j].Name
|
|
}
|
|
return fs[i].ProbeOrder < fs[j].ProbeOrder
|
|
})
|
|
}
|
|
|
|
func (r *Registry) resolve() error {
|
|
for _, fs := range r.Groups {
|
|
for _, f := range fs {
|
|
for _, d := range f.Dependencies {
|
|
var formats []*decode.Format
|
|
for _, dName := range d.Names {
|
|
df, ok := r.Groups[dName]
|
|
if !ok {
|
|
return fmt.Errorf("%s: can't find format dependency %s", f.Name, dName)
|
|
}
|
|
formats = append(formats, df...)
|
|
}
|
|
|
|
sortFormats(formats)
|
|
*d.Formats = formats
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, fs := range r.Groups {
|
|
sortFormats(fs)
|
|
}
|
|
|
|
r.resolved = true
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *Registry) Group(name string) ([]*decode.Format, error) {
|
|
r.resolveOnce.Do(func() {
|
|
if err := r.resolve(); err != nil {
|
|
panic(err)
|
|
}
|
|
})
|
|
|
|
if g, ok := r.Groups[name]; ok {
|
|
return g, nil
|
|
}
|
|
return nil, errors.New("format group not found")
|
|
}
|
|
|
|
func (r *Registry) MustGroup(name string) []*decode.Format {
|
|
g, err := r.Group(name)
|
|
if err == nil {
|
|
return g
|
|
}
|
|
panic(err)
|
|
}
|
|
|
|
func (r *Registry) MustAll() []*decode.Format {
|
|
return r.MustGroup("all")
|
|
}
|