mirror of https://github.com/rocboss/paopao-ce
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
3.7 KiB
150 lines
3.7 KiB
package cfg
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/rocboss/paopao-ce/pkg/types"
|
|
)
|
|
|
|
// Features fetures info struct
|
|
type Features struct {
|
|
kv map[string]string
|
|
suites map[string][]string
|
|
features map[string]string
|
|
}
|
|
|
|
// Actions feature-func map alias type
|
|
type Actions map[string]types.Fn
|
|
|
|
// NewFeatures create new Features instance
|
|
func NewFeatures(suites map[string][]string, kv map[string]string) *Features {
|
|
f := newEmptyFeatures()
|
|
for k, v := range suites {
|
|
if len(k) > 0 {
|
|
for i := 0; i < len(v); i++ {
|
|
// ignore empty string
|
|
if len(v[i]) == 0 {
|
|
lastIdx := len(v) - 1
|
|
v[i] = v[lastIdx]
|
|
v = v[:lastIdx]
|
|
i--
|
|
}
|
|
}
|
|
if len(v) > 0 {
|
|
f.suites[k] = v
|
|
}
|
|
}
|
|
}
|
|
for k, v := range kv {
|
|
if len(k) > 0 && len(v) > 0 {
|
|
f.kv[k] = v
|
|
}
|
|
}
|
|
f.UseDefault()
|
|
return f
|
|
}
|
|
|
|
func newEmptyFeatures() *Features {
|
|
return &Features{
|
|
suites: make(map[string][]string),
|
|
kv: make(map[string]string),
|
|
features: make(map[string]string),
|
|
}
|
|
}
|
|
|
|
// UseDefault use default suite for features
|
|
func (f *Features) UseDefault() {
|
|
f.Use([]string{"default"}, true)
|
|
}
|
|
|
|
// Use use custom suite for features
|
|
func (f *Features) Use(suite []string, noDefault bool) {
|
|
if noDefault && len(f.features) != 0 {
|
|
f.features = make(map[string]string)
|
|
}
|
|
features := f.flatFeatures(suite)
|
|
for _, feature := range features {
|
|
if len(feature) == 0 {
|
|
continue
|
|
}
|
|
f.features[feature] = f.kv[feature]
|
|
}
|
|
}
|
|
|
|
func (f *Features) flatFeatures(suite []string) []string {
|
|
features := make([]string, 0, len(suite)+10)
|
|
for s := suite[:]; len(s) > 0; s = s[:len(s)-1] {
|
|
item := strings.TrimSpace(strings.ToLower(s[0]))
|
|
if len(item) > 0 {
|
|
if items, exist := f.suites[item]; exist {
|
|
s = append(s, items...)
|
|
}
|
|
features = append(features, item)
|
|
}
|
|
s[0] = s[len(s)-1]
|
|
}
|
|
return features
|
|
}
|
|
|
|
// Cfg get value by key if exist
|
|
func (f *Features) Cfg(key string) (string, bool) {
|
|
key = strings.ToLower(key)
|
|
value, exist := f.features[key]
|
|
return value, exist
|
|
}
|
|
|
|
// CfgIf check expression is true. if expression just have a string like
|
|
// `Sms` is mean `Sms` whether define in suite feature settings. expression like
|
|
// `Sms = SmsJuhe` is mean whether `Sms` define in suite feature settings and value
|
|
// is `SmsJuhe`
|
|
func (f *Features) CfgIf(expression string) bool {
|
|
kv := strings.Split(expression, "=")
|
|
key := strings.Trim(strings.ToLower(kv[0]), " ")
|
|
v, ok := f.features[key]
|
|
if len(kv) == 2 && ok && strings.Trim(kv[1], " ") == v {
|
|
return true
|
|
} else if len(kv) == 1 && ok {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// CfgIn range actions to check item's expression is true then do the handle, defFn will handle
|
|
// if all items are not matched,
|
|
func (f *Features) CfgIn(actions Actions, defAct ...types.Fn) {
|
|
itemMatched := false
|
|
for expression, handle := range actions {
|
|
if f.CfgIf(expression) && handle != nil {
|
|
handle()
|
|
itemMatched = true
|
|
}
|
|
}
|
|
if !itemMatched && len(defAct) > 0 {
|
|
for _, handle := range defAct {
|
|
if handle != nil {
|
|
handle()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// CfgBe check expression is true then do the handle. if expression just have a string like
|
|
// `Sms` is mean `Sms` whether defined in suite feature settings. expression like
|
|
// `Sms = SmsJuhe` is mean whether `Sms` define in suite feature settings and value
|
|
// is `SmsJuhe`
|
|
func (f *Features) CfgBe(expression string, handle types.Fn) {
|
|
if f.CfgIf(expression) && handle != nil {
|
|
handle()
|
|
}
|
|
}
|
|
|
|
// CfgNot check expression is not true then do the handle. if expression just have a string like
|
|
// `Sms` is mean `Sms` whether defined in suite feature settings. expression like
|
|
// `Sms = SmsJuhe` is mean whether `Sms` define in suite feature settings and value
|
|
// is `SmsJuhe`
|
|
func (f *Features) CfgNot(expression string, handle func()) {
|
|
if !f.CfgIf(expression) {
|
|
handle()
|
|
}
|
|
}
|