mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 05:40:42 +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
 | |
| }
 |