chore: add generic registry with context support (#15203)
This commit is contained in:
parent
ec9a2ab6e9
commit
ccc9e6c19a
5 changed files with 76 additions and 76 deletions
|
|
@ -1,31 +1,21 @@
|
|||
package charger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
reg "github.com/evcc-io/evcc/util/registry"
|
||||
)
|
||||
|
||||
type chargerRegistry map[string]func(map[string]interface{}) (api.Charger, error)
|
||||
var registry = reg.New[api.Charger]("charger")
|
||||
|
||||
func (r chargerRegistry) Add(name string, factory func(map[string]interface{}) (api.Charger, error)) {
|
||||
if _, exists := r[name]; exists {
|
||||
panic(fmt.Sprintf("cannot register duplicate charger type: %s", name))
|
||||
}
|
||||
r[name] = factory
|
||||
// Types returns the list of types
|
||||
func Types() []string {
|
||||
return registry.Types()
|
||||
}
|
||||
|
||||
func (r chargerRegistry) Get(name string) (func(map[string]interface{}) (api.Charger, error), error) {
|
||||
factory, exists := r[name]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("invalid charger type: %s", name)
|
||||
}
|
||||
return factory, nil
|
||||
}
|
||||
|
||||
var registry chargerRegistry = make(map[string]func(map[string]interface{}) (api.Charger, error))
|
||||
|
||||
// NewFromConfig creates charger from configuration
|
||||
func NewFromConfig(typ string, other map[string]interface{}) (api.Charger, error) {
|
||||
factory, err := registry.Get(strings.ToLower(typ))
|
||||
|
|
@ -33,7 +23,7 @@ func NewFromConfig(typ string, other map[string]interface{}) (api.Charger, error
|
|||
return nil, err
|
||||
}
|
||||
|
||||
v, err := factory(other)
|
||||
v, err := factory(context.TODO(), other)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("cannot create charger type '%s': %w", typ, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,21 @@
|
|||
package meter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
reg "github.com/evcc-io/evcc/util/registry"
|
||||
)
|
||||
|
||||
type meterRegistry map[string]func(map[string]interface{}) (api.Meter, error)
|
||||
var registry = reg.New[api.Meter]("meter")
|
||||
|
||||
func (r meterRegistry) Add(name string, factory func(map[string]interface{}) (api.Meter, error)) {
|
||||
if _, exists := r[name]; exists {
|
||||
panic(fmt.Sprintf("cannot register duplicate meter type: %s", name))
|
||||
}
|
||||
r[name] = factory
|
||||
// Types returns the list of types
|
||||
func Types() []string {
|
||||
return registry.Types()
|
||||
}
|
||||
|
||||
func (r meterRegistry) Get(name string) (func(map[string]interface{}) (api.Meter, error), error) {
|
||||
factory, exists := r[name]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("invalid meter type: %s", name)
|
||||
}
|
||||
return factory, nil
|
||||
}
|
||||
|
||||
var registry meterRegistry = make(map[string]func(map[string]interface{}) (api.Meter, error))
|
||||
|
||||
// NewFromConfig creates meter from configuration
|
||||
func NewFromConfig(typ string, other map[string]interface{}) (api.Meter, error) {
|
||||
factory, err := registry.Get(strings.ToLower(typ))
|
||||
|
|
@ -33,7 +23,7 @@ func NewFromConfig(typ string, other map[string]interface{}) (api.Meter, error)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
v, err := factory(other)
|
||||
v, err := factory(context.TODO(), other)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("cannot create meter type '%s': %w", typ, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,21 @@
|
|||
package tariff
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
reg "github.com/evcc-io/evcc/util/registry"
|
||||
)
|
||||
|
||||
type tariffRegistry map[string]func(map[string]interface{}) (api.Tariff, error)
|
||||
var registry = reg.New[api.Tariff]("tariff")
|
||||
|
||||
func (r tariffRegistry) Add(name string, factory func(map[string]interface{}) (api.Tariff, error)) {
|
||||
if _, exists := r[name]; exists {
|
||||
panic(fmt.Sprintf("cannot register duplicate tariff type: %s", name))
|
||||
}
|
||||
r[name] = factory
|
||||
// Types returns the list of types
|
||||
func Types() []string {
|
||||
return registry.Types()
|
||||
}
|
||||
|
||||
func (r tariffRegistry) Get(name string) (func(map[string]interface{}) (api.Tariff, error), error) {
|
||||
factory, exists := r[name]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("invalid tariff type: %s", name)
|
||||
}
|
||||
return factory, nil
|
||||
}
|
||||
|
||||
var registry tariffRegistry = make(map[string]func(map[string]interface{}) (api.Tariff, error))
|
||||
|
||||
// NewFromConfig creates tariff from configuration
|
||||
func NewFromConfig(typ string, other map[string]interface{}) (api.Tariff, error) {
|
||||
factory, err := registry.Get(strings.ToLower(typ))
|
||||
|
|
@ -33,7 +23,7 @@ func NewFromConfig(typ string, other map[string]interface{}) (api.Tariff, error)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
v, err := factory(other)
|
||||
v, err := factory(context.TODO(), other)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("cannot create tariff type '%s': %w", typ, err)
|
||||
}
|
||||
|
|
|
|||
49
util/registry/registry.go
Normal file
49
util/registry/registry.go
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/exp/maps"
|
||||
)
|
||||
|
||||
type (
|
||||
factoryFunc[T any] func(context.Context, map[string]any) (T, error)
|
||||
|
||||
registry[T any] struct {
|
||||
typ string
|
||||
data map[string]factoryFunc[T]
|
||||
}
|
||||
)
|
||||
|
||||
func (r registry[T]) Add(name string, factory func(map[string]any) (T, error)) {
|
||||
r.AddCtx(name, func(_ context.Context, cc map[string]any) (T, error) {
|
||||
return factory(cc)
|
||||
})
|
||||
}
|
||||
|
||||
func (r registry[T]) AddCtx(name string, factory factoryFunc[T]) {
|
||||
if _, exists := r.data[name]; exists {
|
||||
panic(fmt.Sprintf("cannot register duplicate %s type: %s", r.typ, name))
|
||||
}
|
||||
r.data[name] = factory
|
||||
}
|
||||
|
||||
func (r registry[T]) Get(name string) (factoryFunc[T], error) {
|
||||
factory, exists := r.data[name]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("invalid %s type: %s", r.typ, name)
|
||||
}
|
||||
return factory, nil
|
||||
}
|
||||
|
||||
func (r registry[T]) Types() []string {
|
||||
return maps.Keys(r.data)
|
||||
}
|
||||
|
||||
func New[T any](typ string) registry[T] {
|
||||
return registry[T]{
|
||||
typ: typ,
|
||||
data: make(map[string]factoryFunc[T]),
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,14 @@
|
|||
package vehicle
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
reg "github.com/evcc-io/evcc/util/registry"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -14,32 +16,11 @@ const (
|
|||
interval = 15 * time.Minute // refresh interval when charging
|
||||
)
|
||||
|
||||
type vehicleRegistry map[string]func(map[string]interface{}) (api.Vehicle, error)
|
||||
var registry = reg.New[api.Vehicle]("vehicle")
|
||||
|
||||
func (r vehicleRegistry) Add(name string, factory func(map[string]interface{}) (api.Vehicle, error)) {
|
||||
if _, exists := r[name]; exists {
|
||||
panic(fmt.Sprintf("cannot register duplicate vehicle type: %s", name))
|
||||
}
|
||||
r[name] = factory
|
||||
}
|
||||
|
||||
func (r vehicleRegistry) Get(name string) (func(map[string]interface{}) (api.Vehicle, error), error) {
|
||||
factory, exists := r[name]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("invalid vehicle type: %s", name)
|
||||
}
|
||||
return factory, nil
|
||||
}
|
||||
|
||||
var registry vehicleRegistry = make(map[string]func(map[string]interface{}) (api.Vehicle, error))
|
||||
|
||||
// Types returns the list of vehicle types
|
||||
// Types returns the list of types
|
||||
func Types() []string {
|
||||
var res []string
|
||||
for typ := range registry {
|
||||
res = append(res, typ)
|
||||
}
|
||||
return res
|
||||
return registry.Types()
|
||||
}
|
||||
|
||||
// NewFromConfig creates vehicle from configuration
|
||||
|
|
@ -63,7 +44,7 @@ func NewFromConfig(typ string, other map[string]interface{}) (api.Vehicle, error
|
|||
return nil, err
|
||||
}
|
||||
|
||||
v, err := factory(cc.Other)
|
||||
v, err := factory(context.TODO(), cc.Other)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("cannot create vehicle type '%s': %w", typ, err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue