package filter import ( "errors" "reflect" "strconv" "strings" ) const ( any = '*' anys = string(any) ) type less func(i, j int) bool func reverse(f less) less { return func(i, j int) bool { return f(j, i) } } func index(f Filter, i int, fields []string) (val reflect.Value) { val = reflect.ValueOf(f.Index(i)).FieldByName(fields[0]) for j := 1; j < len(fields); j++ { val = val.FieldByName(fields[j]) } return } func makeLess(f Filter, fields []string) less { switch index(f, 0, fields).Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return func(i, j int) bool { return index(f, i, fields).Int() < index(f, j, fields).Int() } case reflect.Float32, reflect.Float64: return func(i, j int) bool { return index(f, i, fields).Float() < index(f, j, fields).Float() } case reflect.String: return func(i, j int) bool { return index(f, i, fields).String() < index(f, j, fields).String() } case reflect.Bool: return func(i, _ int) bool { return index(f, i, fields).Bool() } } return nil } func getValue(v reflect.Value) (s string, b bool, err error) { switch v.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: s = strconv.FormatInt(v.Int(), 10) case reflect.Float32, reflect.Float64: s = strconv.FormatFloat(v.Float(), 'f', -1, 64) case reflect.String: s = v.String() case reflect.Bool: b = v.Bool() default: err = errors.New("nil") } return } func matchFunc(v string) func(string) bool { vl := len(v) switch { case vl >= 3: if v[0] == any && v[vl-1] == any && v[1] != any && v[vl-2] != any { return func(s string) bool { return strings.Contains(s, v[1:vl-1]) } } fallthrough case vl >= 2: switch { case v[0] == any && v[1] != any: return func(s string) bool { return strings.HasSuffix(s, v[1:]) } case v[vl-1] == any && v[vl-2] != any: return func(s string) bool { return strings.HasPrefix(s, v[:vl-1]) } } } v = strings.Replace(v, anys+anys, anys, -1) return func(s string) bool { if s == v { return true } return false } } func ft(b bool) bool { if b { return true } return false } func ff(b bool) bool { if !b { return true } return false } func f(b bool) bool { return false } func boolFunc(v string) func(bool) bool { if len(v) == 0 { return f } if v[0] == 't' { return ft } if v[0] == 'f' { return ff } return f }