2019-11-22 03:40:09 -06:00
|
|
|
package predict
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"github.com/posener/complete/v2"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Option provides prediction through options pattern.
|
|
|
|
//
|
|
|
|
// Usage:
|
|
|
|
//
|
|
|
|
// func(o ...predict.Option) {
|
|
|
|
// cfg := predict.Options(o)
|
|
|
|
// // use cfg.Predict...
|
|
|
|
// }
|
|
|
|
type Option func(*Config)
|
|
|
|
|
|
|
|
// OptValues allows to set a desired set of valid values for the flag.
|
|
|
|
func OptValues(values ...string) Option {
|
|
|
|
return OptPredictor(Set(values))
|
|
|
|
}
|
|
|
|
|
|
|
|
// OptPredictor allows to set a custom predictor.
|
|
|
|
func OptPredictor(p complete.Predictor) Option {
|
2019-11-22 06:58:47 -06:00
|
|
|
return func(o *Config) {
|
|
|
|
if o.Predictor != nil {
|
|
|
|
panic("predictor set more than once.")
|
|
|
|
}
|
|
|
|
o.Predictor = p
|
|
|
|
}
|
2019-11-22 03:40:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// OptCheck enforces the valid values on the predicted flag.
|
|
|
|
func OptCheck() Option {
|
2019-11-22 06:58:47 -06:00
|
|
|
return func(o *Config) {
|
|
|
|
if o.check {
|
|
|
|
panic("check set more than once")
|
|
|
|
}
|
|
|
|
o.check = true
|
|
|
|
}
|
2019-11-22 03:40:09 -06:00
|
|
|
}
|
|
|
|
|
2019-11-22 07:03:53 -06:00
|
|
|
// Config stores prediction options.
|
2019-11-22 03:40:09 -06:00
|
|
|
type Config struct {
|
|
|
|
complete.Predictor
|
|
|
|
check bool
|
|
|
|
}
|
|
|
|
|
2019-11-22 07:03:53 -06:00
|
|
|
// Options return a config from a list of options.
|
2019-11-22 03:40:09 -06:00
|
|
|
func Options(os ...Option) Config {
|
|
|
|
var op Config
|
|
|
|
for _, f := range os {
|
|
|
|
f(&op)
|
|
|
|
}
|
|
|
|
return op
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c Config) Predict(prefix string) []string {
|
|
|
|
if c.Predictor != nil {
|
|
|
|
return c.Predictor.Predict(prefix)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-11-22 07:03:53 -06:00
|
|
|
// Check checks that value is one of the predicted values, in case
|
|
|
|
// that the check field was set.
|
2019-11-22 03:40:09 -06:00
|
|
|
func (c Config) Check(value string) error {
|
2019-11-22 03:48:06 -06:00
|
|
|
if !c.check || c.Predictor == nil {
|
|
|
|
return nil
|
|
|
|
}
|
2019-11-22 03:40:09 -06:00
|
|
|
predictions := c.Predictor.Predict(value)
|
2019-11-22 03:48:06 -06:00
|
|
|
if len(predictions) == 0 {
|
2019-11-22 03:40:09 -06:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
for _, vv := range predictions {
|
|
|
|
if value == vv {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return fmt.Errorf("not in allowed values: %s", strings.Join(predictions, ","))
|
|
|
|
}
|