Migrate Sirupsen to sirupsen.
This commit is contained in:
parent
c134dcd6fe
commit
fb4ba7af2b
684 changed files with 92394 additions and 33943 deletions
150
vendor/github.com/vulcand/predicate/lib.go
generated
vendored
Normal file
150
vendor/github.com/vulcand/predicate/lib.go
generated
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
Copyright 2016 Vulcand Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package predicate
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
)
|
||||
|
||||
// GetStringMapValue is a helper function that returns property
|
||||
// from map[string]string or map[string][]string
|
||||
// the function returns empty value in case if key not found
|
||||
// In case if map is nil, returns empty value as well
|
||||
func GetStringMapValue(mapVal, keyVal interface{}) (interface{}, error) {
|
||||
key, ok := keyVal.(string)
|
||||
if !ok {
|
||||
return nil, trace.BadParameter("only string keys are supported")
|
||||
}
|
||||
switch m := mapVal.(type) {
|
||||
case map[string][]string:
|
||||
if len(m) == 0 {
|
||||
// to return nil with a proper type
|
||||
var n []string
|
||||
return n, nil
|
||||
}
|
||||
return m[key], nil
|
||||
case map[string]string:
|
||||
if len(m) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
return m[key], nil
|
||||
default:
|
||||
return nil, trace.BadParameter("type %T is not supported", m)
|
||||
}
|
||||
}
|
||||
|
||||
// BoolPredicate is a function without arguments that returns
|
||||
// boolean value when called
|
||||
type BoolPredicate func() bool
|
||||
|
||||
// Equals can compare complex objects, e.g. arrays of strings
|
||||
// and strings together
|
||||
func Equals(a interface{}, b interface{}) BoolPredicate {
|
||||
return func() bool {
|
||||
switch aval := a.(type) {
|
||||
case string:
|
||||
bval, ok := b.(string)
|
||||
return ok && aval == bval
|
||||
case []string:
|
||||
bval, ok := b.([]string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if len(aval) != len(bval) {
|
||||
return false
|
||||
}
|
||||
for i := range aval {
|
||||
if aval[i] != bval[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Contains checks if string slice contains a string
|
||||
// Contains([]string{"a", "b"}, "b") -> true
|
||||
func Contains(a interface{}, b interface{}) BoolPredicate {
|
||||
return func() bool {
|
||||
aval, ok := a.([]string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
bval, ok := b.(string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
for _, v := range aval {
|
||||
if v == bval {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// And is a boolean predicate that calls two boolean predicates
|
||||
// and returns result of && operation on their return values
|
||||
func And(a, b BoolPredicate) BoolPredicate {
|
||||
return func() bool {
|
||||
return a() && b()
|
||||
}
|
||||
}
|
||||
|
||||
// Or is a boolean predicate that calls two boolean predicates
|
||||
// and returns result of || operation on their return values
|
||||
func Or(a, b BoolPredicate) BoolPredicate {
|
||||
return func() bool {
|
||||
return a() || b()
|
||||
}
|
||||
}
|
||||
|
||||
// GetFieldByTag returns a field from the object based on the tag
|
||||
func GetFieldByTag(ival interface{}, tagName string, fieldNames []string) (interface{}, error) {
|
||||
if len(fieldNames) == 0 {
|
||||
return nil, trace.BadParameter("missing field names")
|
||||
}
|
||||
val := reflect.ValueOf(ival)
|
||||
if val.Kind() == reflect.Interface || val.Kind() == reflect.Ptr {
|
||||
val = val.Elem()
|
||||
}
|
||||
if val.Kind() != reflect.Struct {
|
||||
return nil, trace.NotFound("field name %v is not found", strings.Join(fieldNames, "."))
|
||||
}
|
||||
fieldName := fieldNames[0]
|
||||
rest := fieldNames[1:]
|
||||
|
||||
valType := val.Type()
|
||||
for i := 0; i < valType.NumField(); i++ {
|
||||
tagValue := valType.Field(i).Tag.Get(tagName)
|
||||
parts := strings.Split(tagValue, ",")
|
||||
if parts[0] == fieldName {
|
||||
value := val.Field(i).Interface()
|
||||
if len(rest) == 0 {
|
||||
return value, nil
|
||||
}
|
||||
return GetFieldByTag(value, tagName, rest)
|
||||
}
|
||||
}
|
||||
return nil, trace.NotFound("field name %v is not found", strings.Join(fieldNames, "."))
|
||||
}
|
124
vendor/github.com/vulcand/predicate/parse.go
generated
vendored
124
vendor/github.com/vulcand/predicate/parse.go
generated
vendored
|
@ -7,6 +7,9 @@ import (
|
|||
"go/token"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
)
|
||||
|
||||
func NewParser(d Def) (Parser, error) {
|
||||
|
@ -49,7 +52,7 @@ func (p *predicateParser) parseNode(node ast.Node) (interface{}, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
arguments, err := collectLiterals(n.Args)
|
||||
arguments, err := p.evaluateArguments(n.Args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -57,13 +60,92 @@ func (p *predicateParser) parseNode(node ast.Node) (interface{}, error) {
|
|||
case *ast.ParenExpr:
|
||||
return p.parseNode(n.X)
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported %T", node)
|
||||
return nil, trace.BadParameter("unsupported %T", node)
|
||||
}
|
||||
|
||||
func (p *predicateParser) evaluateArguments(nodes []ast.Expr) ([]interface{}, error) {
|
||||
out := make([]interface{}, len(nodes))
|
||||
for i, n := range nodes {
|
||||
val, err := p.evaluateExpr(n)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
out[i] = val
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (p *predicateParser) evaluateExpr(n ast.Expr) (interface{}, error) {
|
||||
switch l := n.(type) {
|
||||
case *ast.BasicLit:
|
||||
val, err := literalToValue(l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return val, nil
|
||||
case *ast.IndexExpr:
|
||||
if p.d.GetProperty == nil {
|
||||
return nil, trace.NotFound("properties are not supported")
|
||||
}
|
||||
mapVal, err := p.evaluateExpr(l.X)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
keyVal, err := p.evaluateExpr(l.Index)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
val, err := p.d.GetProperty(mapVal, keyVal)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
return val, nil
|
||||
case *ast.SelectorExpr:
|
||||
fields, err := evaluateSelector(l, []string{})
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
if p.d.GetIdentifier == nil {
|
||||
return nil, trace.NotFound("%v is not defined", strings.Join(fields, "."))
|
||||
}
|
||||
val, err := p.d.GetIdentifier(fields)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
return val, nil
|
||||
case *ast.Ident:
|
||||
if p.d.GetIdentifier == nil {
|
||||
return nil, trace.NotFound("%v is not defined", l.Name)
|
||||
}
|
||||
val, err := p.d.GetIdentifier([]string{l.Name})
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
return val, nil
|
||||
default:
|
||||
return nil, trace.BadParameter("%T is not supported", n)
|
||||
}
|
||||
}
|
||||
|
||||
// evaluateSelector recursively evaluates the selector field and returns a list
|
||||
// of properties at the end
|
||||
func evaluateSelector(sel *ast.SelectorExpr, fields []string) ([]string, error) {
|
||||
fields = append([]string{sel.Sel.Name}, fields...)
|
||||
switch l := sel.X.(type) {
|
||||
case *ast.SelectorExpr:
|
||||
return evaluateSelector(l, fields)
|
||||
case *ast.Ident:
|
||||
fields = append([]string{l.Name}, fields...)
|
||||
return fields, nil
|
||||
default:
|
||||
return nil, trace.BadParameter("unsupported selector type: %T", l)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *predicateParser) getFunction(name string) (interface{}, error) {
|
||||
v, ok := p.d.Functions[name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unsupported function: %s", name)
|
||||
return nil, trace.BadParameter("unsupported function: %s", name)
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
@ -97,7 +179,7 @@ func (p *predicateParser) getJoinFunction(op token.Token) (interface{}, error) {
|
|||
fn = p.d.Operators.NEQ
|
||||
}
|
||||
if fn == nil {
|
||||
return nil, fmt.Errorf("%v is not supported", op)
|
||||
return nil, trace.BadParameter("%v is not supported", op)
|
||||
}
|
||||
return fn, nil
|
||||
}
|
||||
|
@ -107,62 +189,46 @@ func getIdentifier(node ast.Node) (string, error) {
|
|||
if ok {
|
||||
id, ok := sexpr.X.(*ast.Ident)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("expected selector identifier, got: %T", sexpr.X)
|
||||
return "", trace.BadParameter("expected selector identifier, got: %T", sexpr.X)
|
||||
}
|
||||
return fmt.Sprintf("%s.%s", id.Name, sexpr.Sel.Name), nil
|
||||
}
|
||||
|
||||
id, ok := node.(*ast.Ident)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("expected identifier, got: %T", node)
|
||||
return "", trace.BadParameter("expected identifier, got: %T", node)
|
||||
}
|
||||
return id.Name, nil
|
||||
}
|
||||
|
||||
func collectLiterals(nodes []ast.Expr) ([]interface{}, error) {
|
||||
out := make([]interface{}, len(nodes))
|
||||
for i, n := range nodes {
|
||||
l, ok := n.(*ast.BasicLit)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected literal, got %T", n)
|
||||
}
|
||||
val, err := literalToValue(l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out[i] = val
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func literalToValue(a *ast.BasicLit) (interface{}, error) {
|
||||
switch a.Kind {
|
||||
case token.FLOAT:
|
||||
value, err := strconv.ParseFloat(a.Value, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse argument: %s, error: %s", a.Value, err)
|
||||
return nil, trace.BadParameter("failed to parse argument: %s, error: %s", a.Value, err)
|
||||
}
|
||||
return value, nil
|
||||
case token.INT:
|
||||
value, err := strconv.Atoi(a.Value)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse argument: %s, error: %s", a.Value, err)
|
||||
return nil, trace.BadParameter("failed to parse argument: %s, error: %s", a.Value, err)
|
||||
}
|
||||
return value, nil
|
||||
case token.STRING:
|
||||
value, err := strconv.Unquote(a.Value)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse argument: %s, error: %s", a.Value, err)
|
||||
return nil, trace.BadParameter("failed to parse argument: %s, error: %s", a.Value, err)
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported function argument type: '%v'", a.Kind)
|
||||
return nil, trace.BadParameter("unsupported function argument type: '%v'", a.Kind)
|
||||
}
|
||||
|
||||
func callFunction(f interface{}, args []interface{}) (v interface{}, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = fmt.Errorf("%s", r)
|
||||
err = trace.BadParameter("%s", r)
|
||||
}
|
||||
}()
|
||||
arguments := make([]reflect.Value, len(args))
|
||||
|
@ -182,9 +248,9 @@ func callFunction(f interface{}, args []interface{}) (v interface{}, err error)
|
|||
}
|
||||
err, ok := e.(error)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected error as a second return value, got %T", e)
|
||||
return nil, trace.BadParameter("expected error as a second return value, got %T", e)
|
||||
}
|
||||
return v, err
|
||||
}
|
||||
return nil, fmt.Errorf("expected at least one return argument for '%v'", fn)
|
||||
return nil, trace.BadParameter("expected at least one return argument for '%v'", fn)
|
||||
}
|
||||
|
|
13
vendor/github.com/vulcand/predicate/predicate.go
generated
vendored
13
vendor/github.com/vulcand/predicate/predicate.go
generated
vendored
|
@ -48,8 +48,21 @@ type Def struct {
|
|||
Operators Operators
|
||||
// Function matching is case sensitive, e.g. Len is different from len
|
||||
Functions map[string]interface{}
|
||||
// GetIdentifier returns value of any identifier passed in
|
||||
// in the form []string{"id", "field", "subfield"}
|
||||
GetIdentifier GetIdentifierFn
|
||||
// GetProperty returns property from a map
|
||||
GetProperty GetPropertyFn
|
||||
}
|
||||
|
||||
// GetIdentifierFn function returns identifier based on selector
|
||||
// e.g. id.field.subfield will be passed as.
|
||||
// GetIdentifierFn([]string{"id", "field", "subfield"})
|
||||
type GetIdentifierFn func(selector []string) (interface{}, error)
|
||||
|
||||
// GetPropertyFn reuturns property from a mapVal by key keyVal
|
||||
type GetPropertyFn func(mapVal, keyVal interface{}) (interface{}, error)
|
||||
|
||||
// Operators contain functions for equality and logical comparison.
|
||||
type Operators struct {
|
||||
EQ interface{}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue