nurse/protocols/redis/validation.go
Peter Kurfer 0faff1d481
Some checks failed
Renovate / renovate (push) Successful in 1m8s
Go build / build (push) Failing after 2m3s
chore: cleanup, add docs, refactor some quirks and prepare release
2023-12-04 16:59:10 +01:00

97 lines
2 KiB
Go

package redis
import (
"errors"
"log/slog"
"github.com/redis/go-redis/v9"
"code.icb4dc0.de/prskr/nurse/grammar"
"code.icb4dc0.de/prskr/nurse/validation"
)
var (
_ CmdValidator = (*GenericCmdValidator)(nil)
registry = validation.NewRegistry[redis.Cmder]()
)
func init() {
registry.Register("equals", func() validation.FromCall[redis.Cmder] {
return new(GenericCmdValidator)
})
}
type CmdValidator interface {
Validate(cmder redis.Cmder) error
}
func GenericCommandValidatorFor[T validation.Value](want T) (*GenericCmdValidator, error) {
comparator, err := validation.JSONValueComparatorFor(want)
if err != nil {
return nil, err
}
return &GenericCmdValidator{
comparator: comparator,
}, nil
}
type GenericCmdValidator struct {
comparator validation.ValueComparator
}
func (g *GenericCmdValidator) UnmarshalCall(c grammar.Call) error {
if err := grammar.ValidateParameterCount(c.Params, 1); err != nil {
return err
}
var err error
switch c.Params[0].Type() {
case grammar.ParamTypeInt:
if g.comparator, err = validation.JSONValueComparatorFor(*c.Params[0].Int); err != nil {
return err
}
case grammar.ParamTypeFloat:
if g.comparator, err = validation.JSONValueComparatorFor(*c.Params[0].Float); err != nil {
return err
}
case grammar.ParamTypeString:
if g.comparator, err = validation.JSONValueComparatorFor(*c.Params[0].String); err != nil {
return err
}
case grammar.ParamTypeUnknown:
fallthrough
default:
return errors.New("param type is unknown")
}
return nil
}
func (g *GenericCmdValidator) Validate(cmder redis.Cmder) error {
slog.Default().Debug("Validate Redis result")
if err := cmder.Err(); err != nil {
return err
}
switch in := cmder.(type) {
case *redis.StringCmd:
if err := in.Err(); err != nil {
return err
}
res, err := in.Result()
if err != nil {
return err
}
return g.comparator.Equals(res)
case *redis.StatusCmd:
if err := in.Err(); err != nil {
return err
}
}
return nil
}