evcc-io/plugin/valid.go
2026-08-20 13:36:53 +02:00

88 lines
1.8 KiB
Go

package plugin
import (
"context"
"errors"
"fmt"
"github.com/evcc-io/evcc/util"
)
func init() {
registry.AddCtx("valid", NewValidFromConfig)
}
// validPlugin validates a reading via a second reading
type validPlugin struct {
ctx context.Context
valid func() (bool, error)
value Config
}
// NewValidFromConfig creates valid provider
func NewValidFromConfig(ctx context.Context, other map[string]any) (Plugin, error) {
var cc struct {
Valid, Value Config
}
if err := util.DecodeOther(other, &cc); err != nil {
return nil, err
}
valid, err := cc.Valid.BoolGetter(ctx)
if err != nil {
return nil, fmt.Errorf("valid: %w", err)
}
o := NewValidPlugin(ctx, valid, cc.Value)
return o, nil
}
// NewValidPlugin creates valid provider
func NewValidPlugin(ctx context.Context, valid func() (bool, error), value Config) *validPlugin {
return &validPlugin{
ctx: ctx,
valid: valid,
value: value,
}
}
func (o *validPlugin) validGetter[T any](valuer func(ctx context.Context) (func() (T, error), error)) (func() (T, error), error) {
value, err := valuer(o.ctx)
if err != nil {
return nil, fmt.Errorf("valid: %w", err)
}
return func() (T, error) {
var zero T
valid, err := o.valid()
if err != nil {
return zero, err
}
if !valid {
return zero, errors.New("invalid")
}
return value()
}, nil
}
var _ StringGetter = (*validPlugin)(nil)
func (o *validPlugin) StringGetter() (func() (string, error), error) {
return o.validGetter(o.value.StringGetter)
}
var _ FloatGetter = (*validPlugin)(nil)
func (o *validPlugin) FloatGetter() (func() (float64, error), error) {
return o.validGetter(o.value.FloatGetter)
}
var _ IntGetter = (*validPlugin)(nil)
func (o *validPlugin) IntGetter() (func() (int64, error), error) {
return o.validGetter(o.value.IntGetter)
}