package common import ( "errors" "fmt" ) type FilterResult byte const ( No FilterResult = iota Maybe Yes ) func IfThenElse(condition bool, onSuccess, onFailure FilterResult) FilterResult { var res FilterResult if condition { res = onSuccess } else { res = onFailure } return res } type SchemaEntry interface { String() string DetailedString() string Filter(typ string, val any) FilterResult } type ( Parser func(key, value []byte) (SchemaEntry, Parser, error) FallbackParser func(key, value []byte) (SchemaEntry, Parser) ) func Any(parsers ...Parser) Parser { return func(key, value []byte) (SchemaEntry, Parser, error) { var errs error for _, parser := range parsers { ret, next, err := parser(key, value) if err == nil { return ret, next, nil } errs = errors.Join(errs, err) } return nil, nil, fmt.Errorf("no parser succeeded: %w", errs) } } func WithFallback(parser Parser, fallback FallbackParser) Parser { if parser == nil { return fallback.ToParser() } return func(key, value []byte) (SchemaEntry, Parser, error) { entry, next, err := parser(key, value) if err == nil { return entry, WithFallback(next, fallback), nil } return fallback.ToParser()(key, value) } } func (fp FallbackParser) ToParser() Parser { return func(key, value []byte) (SchemaEntry, Parser, error) { entry, next := fp(key, value) return entry, next, nil } } func (p Parser) ToFallbackParser() FallbackParser { return func(key, value []byte) (SchemaEntry, Parser) { entry, next, err := p(key, value) if err != nil { panic(fmt.Errorf( "couldn't use that parser as a fallback parser, it returned an error: %w", err, )) } return entry, next } }