mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-04 07:49:35 +00:00 
			
		
		
		
	godep restore pushd $GOPATH/src/github.com/appc/spec git co master popd go get go4.org/errorutil rm -rf Godeps godep save ./... git add vendor git add -f $(git ls-files --other vendor/) git co -- Godeps/LICENSES Godeps/.license_file_state Godeps/OWNERS
		
			
				
	
	
		
			186 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			186 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package jmespath
 | 
						|
 | 
						|
import (
 | 
						|
	"errors"
 | 
						|
	"reflect"
 | 
						|
)
 | 
						|
 | 
						|
// IsFalse determines if an object is false based on the JMESPath spec.
 | 
						|
// JMESPath defines false values to be any of:
 | 
						|
// - An empty string array, or hash.
 | 
						|
// - The boolean value false.
 | 
						|
// - nil
 | 
						|
func isFalse(value interface{}) bool {
 | 
						|
	switch v := value.(type) {
 | 
						|
	case bool:
 | 
						|
		return !v
 | 
						|
	case []interface{}:
 | 
						|
		return len(v) == 0
 | 
						|
	case map[string]interface{}:
 | 
						|
		return len(v) == 0
 | 
						|
	case string:
 | 
						|
		return len(v) == 0
 | 
						|
	case nil:
 | 
						|
		return true
 | 
						|
	}
 | 
						|
	// Try the reflection cases before returning false.
 | 
						|
	rv := reflect.ValueOf(value)
 | 
						|
	switch rv.Kind() {
 | 
						|
	case reflect.Struct:
 | 
						|
		// A struct type will never be false, even if
 | 
						|
		// all of its values are the zero type.
 | 
						|
		return false
 | 
						|
	case reflect.Slice, reflect.Map:
 | 
						|
		return rv.Len() == 0
 | 
						|
	case reflect.Ptr:
 | 
						|
		if rv.IsNil() {
 | 
						|
			return true
 | 
						|
		}
 | 
						|
		// If it's a pointer type, we'll try to deref the pointer
 | 
						|
		// and evaluate the pointer value for isFalse.
 | 
						|
		element := rv.Elem()
 | 
						|
		return isFalse(element.Interface())
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
// ObjsEqual is a generic object equality check.
 | 
						|
// It will take two arbitrary objects and recursively determine
 | 
						|
// if they are equal.
 | 
						|
func objsEqual(left interface{}, right interface{}) bool {
 | 
						|
	return reflect.DeepEqual(left, right)
 | 
						|
}
 | 
						|
 | 
						|
// SliceParam refers to a single part of a slice.
 | 
						|
// A slice consists of a start, a stop, and a step, similar to
 | 
						|
// python slices.
 | 
						|
type sliceParam struct {
 | 
						|
	N         int
 | 
						|
	Specified bool
 | 
						|
}
 | 
						|
 | 
						|
// Slice supports [start:stop:step] style slicing that's supported in JMESPath.
 | 
						|
func slice(slice []interface{}, parts []sliceParam) ([]interface{}, error) {
 | 
						|
	computed, err := computeSliceParams(len(slice), parts)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	start, stop, step := computed[0], computed[1], computed[2]
 | 
						|
	result := []interface{}{}
 | 
						|
	if step > 0 {
 | 
						|
		for i := start; i < stop; i += step {
 | 
						|
			result = append(result, slice[i])
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		for i := start; i > stop; i += step {
 | 
						|
			result = append(result, slice[i])
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return result, nil
 | 
						|
}
 | 
						|
 | 
						|
func computeSliceParams(length int, parts []sliceParam) ([]int, error) {
 | 
						|
	var start, stop, step int
 | 
						|
	if !parts[2].Specified {
 | 
						|
		step = 1
 | 
						|
	} else if parts[2].N == 0 {
 | 
						|
		return nil, errors.New("Invalid slice, step cannot be 0")
 | 
						|
	} else {
 | 
						|
		step = parts[2].N
 | 
						|
	}
 | 
						|
	var stepValueNegative bool
 | 
						|
	if step < 0 {
 | 
						|
		stepValueNegative = true
 | 
						|
	} else {
 | 
						|
		stepValueNegative = false
 | 
						|
	}
 | 
						|
 | 
						|
	if !parts[0].Specified {
 | 
						|
		if stepValueNegative {
 | 
						|
			start = length - 1
 | 
						|
		} else {
 | 
						|
			start = 0
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		start = capSlice(length, parts[0].N, step)
 | 
						|
	}
 | 
						|
 | 
						|
	if !parts[1].Specified {
 | 
						|
		if stepValueNegative {
 | 
						|
			stop = -1
 | 
						|
		} else {
 | 
						|
			stop = length
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		stop = capSlice(length, parts[1].N, step)
 | 
						|
	}
 | 
						|
	return []int{start, stop, step}, nil
 | 
						|
}
 | 
						|
 | 
						|
func capSlice(length int, actual int, step int) int {
 | 
						|
	if actual < 0 {
 | 
						|
		actual += length
 | 
						|
		if actual < 0 {
 | 
						|
			if step < 0 {
 | 
						|
				actual = -1
 | 
						|
			} else {
 | 
						|
				actual = 0
 | 
						|
			}
 | 
						|
		}
 | 
						|
	} else if actual >= length {
 | 
						|
		if step < 0 {
 | 
						|
			actual = length - 1
 | 
						|
		} else {
 | 
						|
			actual = length
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return actual
 | 
						|
}
 | 
						|
 | 
						|
// ToArrayNum converts an empty interface type to a slice of float64.
 | 
						|
// If any element in the array cannot be converted, then nil is returned
 | 
						|
// along with a second value of false.
 | 
						|
func toArrayNum(data interface{}) ([]float64, bool) {
 | 
						|
	// Is there a better way to do this with reflect?
 | 
						|
	if d, ok := data.([]interface{}); ok {
 | 
						|
		result := make([]float64, len(d))
 | 
						|
		for i, el := range d {
 | 
						|
			item, ok := el.(float64)
 | 
						|
			if !ok {
 | 
						|
				return nil, false
 | 
						|
			}
 | 
						|
			result[i] = item
 | 
						|
		}
 | 
						|
		return result, true
 | 
						|
	}
 | 
						|
	return nil, false
 | 
						|
}
 | 
						|
 | 
						|
// ToArrayStr converts an empty interface type to a slice of strings.
 | 
						|
// If any element in the array cannot be converted, then nil is returned
 | 
						|
// along with a second value of false.  If the input data could be entirely
 | 
						|
// converted, then the converted data, along with a second value of true,
 | 
						|
// will be returned.
 | 
						|
func toArrayStr(data interface{}) ([]string, bool) {
 | 
						|
	// Is there a better way to do this with reflect?
 | 
						|
	if d, ok := data.([]interface{}); ok {
 | 
						|
		result := make([]string, len(d))
 | 
						|
		for i, el := range d {
 | 
						|
			item, ok := el.(string)
 | 
						|
			if !ok {
 | 
						|
				return nil, false
 | 
						|
			}
 | 
						|
			result[i] = item
 | 
						|
		}
 | 
						|
		return result, true
 | 
						|
	}
 | 
						|
	return nil, false
 | 
						|
}
 | 
						|
 | 
						|
func isSliceType(v interface{}) bool {
 | 
						|
	if v == nil {
 | 
						|
		return false
 | 
						|
	}
 | 
						|
	return reflect.TypeOf(v).Kind() == reflect.Slice
 | 
						|
}
 |