Merge pull request #360 from apelisse/rename-value-to-interface
predicates: Rename Value into Interface
This commit is contained in:
commit
c8107f2ffc
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes 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 predicates
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Interface is a "interface{} predicate". It's a type that decides if an
|
||||
// interface matches or not.
|
||||
type Interface interface {
|
||||
Match(interface{}) bool
|
||||
}
|
||||
|
||||
// InterfaceDeepEqual compares the Interface data with DeepEqual.
|
||||
func InterfaceDeepEqual(v interface{}) Interface {
|
||||
return interfaceEqual{v: v}
|
||||
}
|
||||
|
||||
type interfaceEqual struct {
|
||||
v interface{}
|
||||
}
|
||||
|
||||
func (p interfaceEqual) Match(v interface{}) bool {
|
||||
return reflect.DeepEqual(v, p.v)
|
||||
}
|
||||
|
||||
// InterfaceNot inverses the value of the predicate.
|
||||
func InterfaceNot(predicate Interface) Interface {
|
||||
return interfaceNot{vp: predicate}
|
||||
}
|
||||
|
||||
type interfaceNot struct {
|
||||
vp Interface
|
||||
}
|
||||
|
||||
func (p interfaceNot) Match(v interface{}) bool {
|
||||
return !p.vp.Match(v)
|
||||
}
|
||||
|
||||
// InterfaceAnd returns true if all the sub-predicates are true. If there are
|
||||
// no sub-predicates, always returns true.
|
||||
func InterfaceAnd(predicates ...Interface) Interface {
|
||||
return interfaceAnd{vps: predicates}
|
||||
}
|
||||
|
||||
type interfaceAnd struct {
|
||||
vps []Interface
|
||||
}
|
||||
|
||||
func (p interfaceAnd) Match(i interface{}) bool {
|
||||
for _, vp := range p.vps {
|
||||
if !vp.Match(i) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// InterfaceOr returns true if any sub-predicate is true. If there are no
|
||||
// sub-predicates, always returns false.
|
||||
func InterfaceOr(predicates ...Interface) Interface {
|
||||
vps := []Interface{}
|
||||
|
||||
// Implements "De Morgan's law"
|
||||
for _, vp := range predicates {
|
||||
vps = append(vps, InterfaceNot(vp))
|
||||
}
|
||||
return InterfaceNot(InterfaceAnd(vps...))
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes 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 predicates_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "k8s.io/kubectl/pkg/framework/predicates"
|
||||
)
|
||||
|
||||
type InterfaceTrue struct{}
|
||||
|
||||
func (InterfaceTrue) Match(value interface{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func TestInterfaceNot(t *testing.T) {
|
||||
if InterfaceNot(InterfaceTrue{}).Match(nil) {
|
||||
t.Fatal("InterfaceNot(InterfaceTrue{}) should never match")
|
||||
}
|
||||
if !InterfaceNot(InterfaceNot(InterfaceTrue{})).Match(nil) {
|
||||
t.Fatal("InterfaceNot(InterfaceNot(InterfaceTrue{})) should always match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterfaceAnd(t *testing.T) {
|
||||
if !InterfaceAnd().Match(nil) {
|
||||
t.Fatal("InterfaceAnd() should always match")
|
||||
}
|
||||
if InterfaceAnd(InterfaceNot(InterfaceTrue{})).Match(nil) {
|
||||
t.Fatal("InterfaceAnd(InterfaceNot(InterfaceTrue{})) should never match")
|
||||
}
|
||||
if !InterfaceAnd(InterfaceTrue{}).Match(nil) {
|
||||
t.Fatal("InterfaceAnd(InterfaceTrue{}) should always match")
|
||||
}
|
||||
if !InterfaceAnd(InterfaceTrue{}, InterfaceTrue{}).Match(nil) {
|
||||
t.Fatal("InterfaceAnd(InterfaceTrue{}, InterfaceTrue{}) should always match")
|
||||
}
|
||||
if InterfaceAnd(InterfaceTrue{}, InterfaceNot(InterfaceTrue{}), InterfaceTrue{}).Match(nil) {
|
||||
t.Fatal("InterfaceAnd(InterfaceTrue{}, InterfaceNot(InterfaceTrue{}), InterfaceTrue{}) should never match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterfaceOr(t *testing.T) {
|
||||
if InterfaceOr().Match(nil) {
|
||||
t.Fatal("InterfaceOr() should never match")
|
||||
}
|
||||
if InterfaceOr(InterfaceNot(InterfaceTrue{})).Match(nil) {
|
||||
t.Fatal("InterfaceOr(InterfaceNot(InterfaceTrue{})) should never match")
|
||||
}
|
||||
if !InterfaceOr(InterfaceTrue{}).Match(nil) {
|
||||
t.Fatal("InterfaceOr(InterfaceTrue{}) should always match")
|
||||
}
|
||||
if !InterfaceOr(InterfaceTrue{}, InterfaceTrue{}).Match(nil) {
|
||||
t.Fatal("InterfaceOr(InterfaceTrue{}, InterfaceTrue{}) should always match")
|
||||
}
|
||||
if !InterfaceOr(InterfaceTrue{}, InterfaceNot(InterfaceTrue{}), InterfaceTrue{}).Match(nil) {
|
||||
t.Fatal("InterfaceOr(InterfaceTrue{}, InterfaceNot(InterfaceTrue{}), InterfaceTrue{}) should always match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterfaceDeepEqual(t *testing.T) {
|
||||
if !InterfaceDeepEqual([]int{1, 2, 3}).Match([]int{1, 2, 3}) {
|
||||
t.Fatal("InterfaceDeepEqual([]int{1, 2, 3}) should match []int{1, 2, 3}")
|
||||
}
|
||||
if InterfaceDeepEqual([]int{1, 2, 3}).Match([]int{1, 2, 4}) {
|
||||
t.Fatal("InterfaceDeepEqual([]int{1, 2, 3}) should not match []int{1, 2, 4}")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes 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 predicates
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Value is a "value predicate". It's a type that decides if a
|
||||
// value matches or not.
|
||||
type Value interface {
|
||||
Match(interface{}) bool
|
||||
}
|
||||
|
||||
// ValueDeepEqual compares the Value data with DeepEqual.
|
||||
func ValueDeepEqual(v interface{}) Value {
|
||||
return valueEqual{v: v}
|
||||
}
|
||||
|
||||
type valueEqual struct {
|
||||
v interface{}
|
||||
}
|
||||
|
||||
func (p valueEqual) Match(v interface{}) bool {
|
||||
return reflect.DeepEqual(v, p.v)
|
||||
}
|
||||
|
||||
// ValueNot inverses the value of the predicate.
|
||||
func ValueNot(predicate Value) Value {
|
||||
return valueNot{vp: predicate}
|
||||
}
|
||||
|
||||
type valueNot struct {
|
||||
vp Value
|
||||
}
|
||||
|
||||
func (p valueNot) Match(v interface{}) bool {
|
||||
return !p.vp.Match(v)
|
||||
}
|
||||
|
||||
// ValueAnd returns true if all the sub-predicates are true. If there are
|
||||
// no sub-predicates, always returns true.
|
||||
func ValueAnd(predicates ...Value) Value {
|
||||
return valueAnd{vps: predicates}
|
||||
}
|
||||
|
||||
type valueAnd struct {
|
||||
vps []Value
|
||||
}
|
||||
|
||||
func (p valueAnd) Match(value interface{}) bool {
|
||||
for _, vp := range p.vps {
|
||||
if !vp.Match(value) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ValueOr returns true if any sub-predicate is true. If there are no
|
||||
// sub-predicates, always returns false.
|
||||
func ValueOr(predicates ...Value) Value {
|
||||
vps := []Value{}
|
||||
|
||||
// Implements "De Morgan's law"
|
||||
for _, vp := range predicates {
|
||||
vps = append(vps, ValueNot(vp))
|
||||
}
|
||||
return ValueNot(ValueAnd(vps...))
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes 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 predicates_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "k8s.io/kubectl/pkg/framework/predicates"
|
||||
)
|
||||
|
||||
type ValueTrue struct{}
|
||||
|
||||
func (ValueTrue) Match(value interface{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func TestValueNot(t *testing.T) {
|
||||
if ValueNot(ValueTrue{}).Match(nil) {
|
||||
t.Fatal("ValueNot(ValueTrue{}) should never match")
|
||||
}
|
||||
if !ValueNot(ValueNot(ValueTrue{})).Match(nil) {
|
||||
t.Fatal("ValueNot(ValueNot(ValueTrue{})) should always match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValueAnd(t *testing.T) {
|
||||
if !ValueAnd().Match(nil) {
|
||||
t.Fatal("ValueAnd() should always match")
|
||||
}
|
||||
if ValueAnd(ValueNot(ValueTrue{})).Match(nil) {
|
||||
t.Fatal("ValueAnd(ValueNot(ValueTrue{})) should never match")
|
||||
}
|
||||
if !ValueAnd(ValueTrue{}).Match(nil) {
|
||||
t.Fatal("ValueAnd(ValueTrue{}) should always match")
|
||||
}
|
||||
if !ValueAnd(ValueTrue{}, ValueTrue{}).Match(nil) {
|
||||
t.Fatal("ValueAnd(ValueTrue{}, ValueTrue{}) should always match")
|
||||
}
|
||||
if ValueAnd(ValueTrue{}, ValueNot(ValueTrue{}), ValueTrue{}).Match(nil) {
|
||||
t.Fatal("ValueAnd(ValueTrue{}, ValueNot(ValueTrue{}), ValueTrue{}) should never match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValueOr(t *testing.T) {
|
||||
if ValueOr().Match(nil) {
|
||||
t.Fatal("ValueOr() should never match")
|
||||
}
|
||||
if ValueOr(ValueNot(ValueTrue{})).Match(nil) {
|
||||
t.Fatal("ValueOr(ValueNot(ValueTrue{})) should never match")
|
||||
}
|
||||
if !ValueOr(ValueTrue{}).Match(nil) {
|
||||
t.Fatal("ValueOr(ValueTrue{}) should always match")
|
||||
}
|
||||
if !ValueOr(ValueTrue{}, ValueTrue{}).Match(nil) {
|
||||
t.Fatal("ValueOr(ValueTrue{}, ValueTrue{}) should always match")
|
||||
}
|
||||
if !ValueOr(ValueTrue{}, ValueNot(ValueTrue{}), ValueTrue{}).Match(nil) {
|
||||
t.Fatal("ValueOr(ValueTrue{}, ValueNot(ValueTrue{}), ValueTrue{}) should always match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValueDeepEqual(t *testing.T) {
|
||||
if !ValueDeepEqual([]int{1, 2, 3}).Match([]int{1, 2, 3}) {
|
||||
t.Fatal("ValueDeepEqual([]int{1, 2, 3}) should match []int{1, 2, 3}")
|
||||
}
|
||||
if ValueDeepEqual([]int{1, 2, 3}).Match([]int{1, 2, 4}) {
|
||||
t.Fatal("ValueDeepEqual([]int{1, 2, 3}) should not match []int{1, 2, 4}")
|
||||
}
|
||||
}
|
||||
|
|
@ -20,20 +20,20 @@ import (
|
|||
p "k8s.io/kubectl/pkg/framework/predicates"
|
||||
)
|
||||
|
||||
// A valueFilter allows us to chain ValueS to ValueS. None of this is
|
||||
// public. It's implementing the "SelectFrom" part of a ValueS.
|
||||
type valueFilter interface {
|
||||
// A interfaceFilter allows us to chain InterfaceS to InterfaceS. None of this is
|
||||
// public. It's implementing the "SelectFrom" part of a InterfaceS.
|
||||
type interfaceFilter interface {
|
||||
SelectFrom(...interface{}) []interface{}
|
||||
}
|
||||
|
||||
// valueFilterP filters using a predicate.
|
||||
type valueFilterP struct {
|
||||
vp p.Value
|
||||
// interfaceFilterP filters using a predicate.
|
||||
type interfaceFilterP struct {
|
||||
vp p.Interface
|
||||
}
|
||||
|
||||
func (f *valueFilterP) SelectFrom(values ...interface{}) []interface{} {
|
||||
func (f *interfaceFilterP) SelectFrom(interfaces ...interface{}) []interface{} {
|
||||
vs := []interface{}{}
|
||||
for _, value := range values {
|
||||
for _, value := range interfaces {
|
||||
if f.vp.Match(value) {
|
||||
vs = append(vs, value)
|
||||
}
|
||||
|
|
@ -41,13 +41,13 @@ func (f *valueFilterP) SelectFrom(values ...interface{}) []interface{} {
|
|||
return vs
|
||||
}
|
||||
|
||||
type valueChildrenFilter struct{}
|
||||
type interfaceChildrenFilter struct{}
|
||||
|
||||
func (valueChildrenFilter) SelectFrom(values ...interface{}) []interface{} {
|
||||
func (interfaceChildrenFilter) SelectFrom(interfaces ...interface{}) []interface{} {
|
||||
children := []interface{}{}
|
||||
// We could process all slices and then all maps, but we want to
|
||||
// keep things in the same order.
|
||||
for _, value := range values {
|
||||
for _, value := range interfaces {
|
||||
// Only one of the two should do something useful.
|
||||
children = append(children, Slice().Children().SelectFrom(value)...)
|
||||
children = append(children, Map().Children().SelectFrom(value)...)
|
||||
|
|
@ -55,33 +55,33 @@ func (valueChildrenFilter) SelectFrom(values ...interface{}) []interface{} {
|
|||
return children
|
||||
}
|
||||
|
||||
// valueSliceFilter is a Value-to-Slice combined with a Slice-to-Value
|
||||
// to form a Value-to-Value.
|
||||
type valueSliceFilter struct {
|
||||
// interfaceSliceFilter is a Interface-to-Slice combined with a Slice-to-Interface
|
||||
// to form a Interface-to-Interface.
|
||||
type interfaceSliceFilter struct {
|
||||
ss SliceS
|
||||
sf sliceFilter
|
||||
}
|
||||
|
||||
func (s *valueSliceFilter) SelectFrom(values ...interface{}) []interface{} {
|
||||
return s.sf.SelectFrom(s.ss.SelectFrom(values...)...)
|
||||
func (s *interfaceSliceFilter) SelectFrom(interfaces ...interface{}) []interface{} {
|
||||
return s.sf.SelectFrom(s.ss.SelectFrom(interfaces...)...)
|
||||
}
|
||||
|
||||
// valueMapFilter is a Value-to-Map combined with a Map-to-Value to form
|
||||
// a Value-to-Value.
|
||||
type valueMapFilter struct {
|
||||
// interfaceMapFilter is a Interface-to-Map combined with a Map-to-Interface to form
|
||||
// a Interface-to-Interface.
|
||||
type interfaceMapFilter struct {
|
||||
ms MapS
|
||||
mf mapFilter
|
||||
}
|
||||
|
||||
func (s *valueMapFilter) SelectFrom(values ...interface{}) []interface{} {
|
||||
return s.mf.SelectFrom(s.ms.SelectFrom(values...)...)
|
||||
func (s *interfaceMapFilter) SelectFrom(interfaces ...interface{}) []interface{} {
|
||||
return s.mf.SelectFrom(s.ms.SelectFrom(interfaces...)...)
|
||||
}
|
||||
|
||||
type valueAllFilter struct{}
|
||||
type interfaceAllFilter struct{}
|
||||
|
||||
func (valueAllFilter) SelectFrom(values ...interface{}) []interface{} {
|
||||
func (interfaceAllFilter) SelectFrom(interfaces ...interface{}) []interface{} {
|
||||
vs := []interface{}{}
|
||||
for _, value := range values {
|
||||
for _, value := range interfaces {
|
||||
vs = append(vs, value)
|
||||
// Only one of the follow two statements should return something ...
|
||||
vs = append(vs, Slice().All().SelectFrom(value)...)
|
||||
|
|
@ -20,15 +20,15 @@ import (
|
|||
p "k8s.io/kubectl/pkg/framework/predicates"
|
||||
)
|
||||
|
||||
// ValueS is a "value selector". It filters values based on the
|
||||
// InterfaceS is a "interface selector". It filters interfaces based on the
|
||||
// "filtered" predicates.
|
||||
type ValueS interface {
|
||||
// ValueS can be used as a Value predicate. If the selector can't
|
||||
// select any value from the value, then the predicate is
|
||||
type InterfaceS interface {
|
||||
// InterfaceS can be used as a Interface predicate. If the selector can't
|
||||
// select any interface from the interface, then the predicate is
|
||||
// false.
|
||||
p.Value
|
||||
p.Interface
|
||||
|
||||
// SelectFrom finds values from values using this selector. The
|
||||
// SelectFrom finds interfaces from interfaces using this selector. The
|
||||
// list can be bigger or smaller than the initial lists,
|
||||
// depending on the select criterias.
|
||||
SelectFrom(...interface{}) []interface{}
|
||||
|
|
@ -46,75 +46,75 @@ type ValueS interface {
|
|||
|
||||
// Children returns a selector that selects the direct children
|
||||
// of the given values.
|
||||
Children() ValueS
|
||||
Children() InterfaceS
|
||||
// All returns a selector that selects all direct and indrect
|
||||
// children of the given values.
|
||||
All() ValueS
|
||||
All() InterfaceS
|
||||
|
||||
// Filter will create a new StringS that filters only the values
|
||||
// who match the predicate.
|
||||
Filter(...p.Value) ValueS
|
||||
Filter(...p.Interface) InterfaceS
|
||||
}
|
||||
|
||||
// Children selects all the children of the values.
|
||||
func Children() ValueS {
|
||||
return &valueS{vf: valueChildrenFilter{}}
|
||||
func Children() InterfaceS {
|
||||
return &interfaceS{vf: interfaceChildrenFilter{}}
|
||||
}
|
||||
|
||||
// All selects all the direct and indirect childrens of the values.
|
||||
func All() ValueS {
|
||||
return &valueS{vf: valueAllFilter{}}
|
||||
func All() InterfaceS {
|
||||
return &interfaceS{vf: interfaceAllFilter{}}
|
||||
}
|
||||
|
||||
// Filter will only return the values that match the predicate.
|
||||
func Filter(predicates ...p.Value) ValueS {
|
||||
return &valueS{vf: &valueFilterP{vp: p.ValueAnd(predicates...)}}
|
||||
func Filter(predicates ...p.Interface) InterfaceS {
|
||||
return &interfaceS{vf: &interfaceFilterP{vp: p.InterfaceAnd(predicates...)}}
|
||||
}
|
||||
|
||||
// ValueS is a "Value SelectFromor". It selects a list of values, maps,
|
||||
// InterfaceS is a "Interface SelectFromor". It selects a list of values, maps,
|
||||
// slices, strings, integer from a list of values.
|
||||
type valueS struct {
|
||||
vs ValueS
|
||||
vf valueFilter
|
||||
type interfaceS struct {
|
||||
vs InterfaceS
|
||||
vf interfaceFilter
|
||||
}
|
||||
|
||||
// Match returns true if the selector can find items in the given
|
||||
// value. Otherwise, it returns false.
|
||||
func (s *valueS) Match(value interface{}) bool {
|
||||
func (s *interfaceS) Match(value interface{}) bool {
|
||||
return len(s.SelectFrom(value)) != 0
|
||||
}
|
||||
|
||||
func (s *valueS) SelectFrom(values ...interface{}) []interface{} {
|
||||
func (s *interfaceS) SelectFrom(interfaces ...interface{}) []interface{} {
|
||||
if s.vs != nil {
|
||||
values = s.vs.SelectFrom(values...)
|
||||
interfaces = s.vs.SelectFrom(interfaces...)
|
||||
}
|
||||
return s.vf.SelectFrom(values...)
|
||||
return s.vf.SelectFrom(interfaces...)
|
||||
}
|
||||
|
||||
func (s *valueS) Map() MapS {
|
||||
func (s *interfaceS) Map() MapS {
|
||||
return &mapS{vs: s}
|
||||
}
|
||||
|
||||
func (s *valueS) Slice() SliceS {
|
||||
func (s *interfaceS) Slice() SliceS {
|
||||
return &sliceS{vs: s}
|
||||
}
|
||||
|
||||
func (s *valueS) Number() NumberS {
|
||||
func (s *interfaceS) Number() NumberS {
|
||||
return &numberS{vs: s}
|
||||
}
|
||||
|
||||
func (s *valueS) String() StringS {
|
||||
func (s *interfaceS) String() StringS {
|
||||
return &stringS{vs: s}
|
||||
}
|
||||
|
||||
func (s *valueS) Children() ValueS {
|
||||
return &valueS{vs: s, vf: valueChildrenFilter{}}
|
||||
func (s *interfaceS) Children() InterfaceS {
|
||||
return &interfaceS{vs: s, vf: interfaceChildrenFilter{}}
|
||||
}
|
||||
|
||||
func (s *valueS) All() ValueS {
|
||||
return &valueS{vs: s, vf: valueAllFilter{}}
|
||||
func (s *interfaceS) All() InterfaceS {
|
||||
return &interfaceS{vs: s, vf: interfaceAllFilter{}}
|
||||
}
|
||||
|
||||
func (s *valueS) Filter(predicates ...p.Value) ValueS {
|
||||
return &valueS{vs: s, vf: &valueFilterP{vp: p.ValueAnd(predicates...)}}
|
||||
func (s *interfaceS) Filter(predicates ...p.Interface) InterfaceS {
|
||||
return &interfaceS{vs: s, vf: &interfaceFilterP{vp: p.InterfaceAnd(predicates...)}}
|
||||
}
|
||||
|
|
@ -66,13 +66,13 @@ func TestFilter(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestValueSPredicate(t *testing.T) {
|
||||
func TestInterfaceSPredicate(t *testing.T) {
|
||||
if !unstructpath.Slice().Match([]interface{}{}) {
|
||||
t.Fatal("SelectFroming a slice from a slice should match.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValueSMap(t *testing.T) {
|
||||
func TestInterfaceSMap(t *testing.T) {
|
||||
root := map[string]interface{}{
|
||||
"key1": "value",
|
||||
"key2": 1,
|
||||
|
|
@ -98,7 +98,7 @@ func TestValueSMap(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestValueSSlice(t *testing.T) {
|
||||
func TestInterfaceSSlice(t *testing.T) {
|
||||
root := map[string]interface{}{
|
||||
"key1": "value",
|
||||
"key2": 1,
|
||||
|
|
@ -124,7 +124,7 @@ func TestValueSSlice(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestValueSChildren(t *testing.T) {
|
||||
func TestInterfaceSChildren(t *testing.T) {
|
||||
root := map[string]interface{}{
|
||||
"key1": "value",
|
||||
"key2": 1,
|
||||
|
|
@ -150,7 +150,7 @@ func TestValueSChildren(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestValueSNumber(t *testing.T) {
|
||||
func TestInterfaceSNumber(t *testing.T) {
|
||||
u := []interface{}{1., 2., "three", 4., 5., []interface{}{}}
|
||||
|
||||
numbers := unstructpath.Children().Number().SelectFrom(u)
|
||||
|
|
@ -161,7 +161,7 @@ func TestValueSNumber(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestValueSString(t *testing.T) {
|
||||
func TestInterfaceSString(t *testing.T) {
|
||||
root := map[string]interface{}{
|
||||
"key1": "value",
|
||||
"key2": 1,
|
||||
|
|
@ -188,7 +188,7 @@ func TestValueSString(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestValueSAll(t *testing.T) {
|
||||
func TestInterfaceSAll(t *testing.T) {
|
||||
root := map[string]interface{}{
|
||||
"key1": "value",
|
||||
"key2": 1,
|
||||
|
|
@ -22,14 +22,14 @@ import (
|
|||
p "k8s.io/kubectl/pkg/framework/predicates"
|
||||
)
|
||||
|
||||
// This is a Map-to-Value filter.
|
||||
// This is a Map-to-Interface filter.
|
||||
type mapFilter interface {
|
||||
SelectFrom(...map[string]interface{}) []interface{}
|
||||
}
|
||||
|
||||
func filterMap(ms MapS, mf mapFilter) ValueS {
|
||||
return &valueS{
|
||||
vf: &valueMapFilter{
|
||||
func filterMap(ms MapS, mf mapFilter) InterfaceS {
|
||||
return &interfaceS{
|
||||
vf: &interfaceMapFilter{
|
||||
ms: ms,
|
||||
mf: mf,
|
||||
},
|
||||
|
|
@ -41,29 +41,29 @@ type mapFieldPFilter struct {
|
|||
}
|
||||
|
||||
func (f mapFieldPFilter) SelectFrom(maps ...map[string]interface{}) []interface{} {
|
||||
values := []interface{}{}
|
||||
interfaces := []interface{}{}
|
||||
|
||||
for _, m := range maps {
|
||||
for _, field := range sortedKeys(m) {
|
||||
if !f.sp.Match(field) {
|
||||
continue
|
||||
}
|
||||
values = append(values, m[field])
|
||||
interfaces = append(interfaces, m[field])
|
||||
}
|
||||
}
|
||||
return values
|
||||
return interfaces
|
||||
}
|
||||
|
||||
type mapAllFilter struct{}
|
||||
|
||||
func (mapAllFilter) SelectFrom(maps ...map[string]interface{}) []interface{} {
|
||||
values := []interface{}{}
|
||||
interfaces := []interface{}{}
|
||||
for _, m := range maps {
|
||||
for _, field := range sortedKeys(m) {
|
||||
values = append(values, All().SelectFrom(m[field])...)
|
||||
interfaces = append(interfaces, All().SelectFrom(m[field])...)
|
||||
}
|
||||
}
|
||||
return values
|
||||
return interfaces
|
||||
}
|
||||
|
||||
func sortedKeys(m map[string]interface{}) []string {
|
||||
|
|
|
|||
|
|
@ -20,60 +20,60 @@ import (
|
|||
p "k8s.io/kubectl/pkg/framework/predicates"
|
||||
)
|
||||
|
||||
// MapS is a "map selector". It selects values as maps (if
|
||||
// MapS is a "map selector". It selects interfaces as maps (if
|
||||
// possible) and filters those maps based on the "filtered"
|
||||
// predicates.
|
||||
type MapS interface {
|
||||
// MapS can be used as a Value predicate. If the selector can't
|
||||
// select any map from the value, then the predicate is
|
||||
// MapS can be used as a Interface predicate. If the selector can't
|
||||
// select any map from the interface, then the predicate is
|
||||
// false.
|
||||
p.Value
|
||||
p.Interface
|
||||
|
||||
// SelectFrom finds maps from values using this selector. The
|
||||
// SelectFrom finds maps from interfaces using this selector. The
|
||||
// list can be bigger or smaller than the initial lists,
|
||||
// depending on the select criterias.
|
||||
SelectFrom(...interface{}) []map[string]interface{}
|
||||
|
||||
// Field returns the value pointed by this specific field in the
|
||||
// Field returns the interface pointed by this specific field in the
|
||||
// map. If the field doesn't exist, the value will be filtered
|
||||
// out.
|
||||
Field(string) ValueS
|
||||
// FieldP returns all the values pointed by field that match the
|
||||
Field(string) InterfaceS
|
||||
// FieldP returns all the interfaces pointed by field that match the
|
||||
// string predicate. This selector can return more values than
|
||||
// it gets (for one map, it can returns multiple sub-values, one
|
||||
// for each field that matches the predicate).
|
||||
FieldP(...p.String) ValueS
|
||||
FieldP(...p.String) InterfaceS
|
||||
|
||||
// All returns a selector that selects all direct and indrect
|
||||
// children of the given values.
|
||||
Children() ValueS
|
||||
Children() InterfaceS
|
||||
// All returns a selector that selects all direct and indrect
|
||||
// children of the given values.
|
||||
All() ValueS
|
||||
All() InterfaceS
|
||||
|
||||
// Filter will create a new MapS that filters only the values
|
||||
// who match the predicate.
|
||||
Filter(...p.Map) MapS
|
||||
}
|
||||
|
||||
// Map creates a selector that takes values and filters them into maps
|
||||
// Map creates a selector that takes interfaces and filters them into maps
|
||||
// if possible.
|
||||
func Map() MapS {
|
||||
return &mapS{}
|
||||
}
|
||||
|
||||
type mapS struct {
|
||||
vs ValueS
|
||||
vs InterfaceS
|
||||
mp p.Map
|
||||
}
|
||||
|
||||
func (s *mapS) SelectFrom(values ...interface{}) []map[string]interface{} {
|
||||
func (s *mapS) SelectFrom(interfaces ...interface{}) []map[string]interface{} {
|
||||
if s.vs != nil {
|
||||
values = s.vs.SelectFrom(values...)
|
||||
interfaces = s.vs.SelectFrom(interfaces...)
|
||||
}
|
||||
|
||||
maps := []map[string]interface{}{}
|
||||
for _, value := range values {
|
||||
for _, value := range interfaces {
|
||||
m, ok := value.(map[string]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
|
|
@ -87,20 +87,20 @@ func (s *mapS) SelectFrom(values ...interface{}) []map[string]interface{} {
|
|||
return maps
|
||||
}
|
||||
|
||||
func (s *mapS) Field(str string) ValueS {
|
||||
func (s *mapS) Field(str string) InterfaceS {
|
||||
return s.FieldP(p.StringEqual(str))
|
||||
}
|
||||
|
||||
func (s *mapS) FieldP(predicates ...p.String) ValueS {
|
||||
func (s *mapS) FieldP(predicates ...p.String) InterfaceS {
|
||||
return filterMap(s, mapFieldPFilter{sp: p.StringAnd(predicates...)})
|
||||
}
|
||||
|
||||
func (s *mapS) Children() ValueS {
|
||||
func (s *mapS) Children() InterfaceS {
|
||||
// No predicate means select all.
|
||||
return s.FieldP()
|
||||
}
|
||||
|
||||
func (s *mapS) All() ValueS {
|
||||
func (s *mapS) All() InterfaceS {
|
||||
return filterMap(s, mapAllFilter{})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ import (
|
|||
// possible) and filters those numbers based on the "filtered"
|
||||
// predicates.
|
||||
type NumberS interface {
|
||||
// NumberS can be used as a Value predicate. If the selector can't
|
||||
// NumberS can be used as a Interface predicate. If the selector can't
|
||||
// select any number from the value, then the predicate is
|
||||
// false.
|
||||
p.Value
|
||||
p.Interface
|
||||
|
||||
// SelectFrom finds numbers from values using this selector. The
|
||||
// list can be bigger or smaller than the initial lists,
|
||||
|
|
@ -45,7 +45,7 @@ func Number() NumberS {
|
|||
}
|
||||
|
||||
type numberS struct {
|
||||
vs ValueS
|
||||
vs InterfaceS
|
||||
ip p.Number
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ func TestNumberSPredicate(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNumberSFromValueS(t *testing.T) {
|
||||
func TestNumberSFromInterfaceS(t *testing.T) {
|
||||
if !Children().Number().Filter(p.NumberGreaterThan(10)).Match([]interface{}{1., 2., 5., 12.}) {
|
||||
t.Fatal("SelectFromor should find element that match")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,16 +20,16 @@ import (
|
|||
p "k8s.io/kubectl/pkg/framework/predicates"
|
||||
)
|
||||
|
||||
func filterSlice(ss SliceS, sf sliceFilter) ValueS {
|
||||
return &valueS{
|
||||
vf: &valueSliceFilter{
|
||||
func filterSlice(ss SliceS, sf sliceFilter) InterfaceS {
|
||||
return &interfaceS{
|
||||
vf: &interfaceSliceFilter{
|
||||
ss: ss,
|
||||
sf: sf,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// This is a Slice-to-Value filter.
|
||||
// This is a Slice-to-Interface filter.
|
||||
type sliceFilter interface {
|
||||
SelectFrom(...[]interface{}) []interface{}
|
||||
}
|
||||
|
|
@ -39,40 +39,40 @@ type sliceAtPFilter struct {
|
|||
}
|
||||
|
||||
func (f sliceAtPFilter) SelectFrom(slices ...[]interface{}) []interface{} {
|
||||
values := []interface{}{}
|
||||
interfaces := []interface{}{}
|
||||
|
||||
for _, slice := range slices {
|
||||
for i := range slice {
|
||||
if !f.ip.Match(float64(i)) {
|
||||
continue
|
||||
}
|
||||
values = append(values, slice[i])
|
||||
interfaces = append(interfaces, slice[i])
|
||||
}
|
||||
}
|
||||
return values
|
||||
return interfaces
|
||||
}
|
||||
|
||||
type sliceLastFilter struct{}
|
||||
|
||||
func (f sliceLastFilter) SelectFrom(slices ...[]interface{}) []interface{} {
|
||||
values := []interface{}{}
|
||||
interfaces := []interface{}{}
|
||||
for _, slice := range slices {
|
||||
if len(slice) == 0 {
|
||||
continue
|
||||
}
|
||||
values = append(values, slice[len(slice)-1])
|
||||
interfaces = append(interfaces, slice[len(slice)-1])
|
||||
}
|
||||
return values
|
||||
return interfaces
|
||||
}
|
||||
|
||||
type sliceAllFilter struct{}
|
||||
|
||||
func (sliceAllFilter) SelectFrom(slices ...[]interface{}) []interface{} {
|
||||
values := []interface{}{}
|
||||
interfaces := []interface{}{}
|
||||
for _, slice := range slices {
|
||||
for _, v := range slice {
|
||||
values = append(values, All().SelectFrom(v)...)
|
||||
interfaces = append(interfaces, All().SelectFrom(v)...)
|
||||
}
|
||||
}
|
||||
return values
|
||||
return interfaces
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ import (
|
|||
// possible) and filters those slices based on the "filtered"
|
||||
// predicates.
|
||||
type SliceS interface {
|
||||
// SliceS can be used as a Value predicate. If the selector
|
||||
// SliceS can be used as a Interface predicate. If the selector
|
||||
// can't select any slice from the value, then the predicate is
|
||||
// false.
|
||||
p.Value
|
||||
p.Interface
|
||||
|
||||
// SelectFrom finds slices from values using this selector. The
|
||||
// list can be bigger or smaller than the initial lists,
|
||||
|
|
@ -37,21 +37,21 @@ type SliceS interface {
|
|||
// At returns a selector that select the child at the given
|
||||
// index, if the list has such an index. Otherwise, nothing is
|
||||
// returned.
|
||||
At(index int) ValueS
|
||||
At(index int) InterfaceS
|
||||
// AtP returns a selector that selects all the item whose index
|
||||
// matches the number predicate. More predicates can be given,
|
||||
// they are "and"-ed by this method.
|
||||
AtP(ips ...p.Number) ValueS
|
||||
AtP(ips ...p.Number) InterfaceS
|
||||
// Last returns a selector that selects the last value of the
|
||||
// list. If the list is empty, then nothing will be selected.
|
||||
Last() ValueS
|
||||
Last() InterfaceS
|
||||
|
||||
// All returns a selector that selects all direct and indrect
|
||||
// children of the given values.
|
||||
Children() ValueS
|
||||
Children() InterfaceS
|
||||
// All returns a selector that selects all direct and indrect
|
||||
// children of the given values.
|
||||
All() ValueS
|
||||
All() InterfaceS
|
||||
|
||||
// Filter will create a new SliceS that filters only the values
|
||||
// who match the predicate.
|
||||
|
|
@ -65,17 +65,17 @@ func Slice() SliceS {
|
|||
}
|
||||
|
||||
type sliceS struct {
|
||||
vs ValueS
|
||||
vs InterfaceS
|
||||
sp p.Slice
|
||||
}
|
||||
|
||||
func (s *sliceS) SelectFrom(values ...interface{}) [][]interface{} {
|
||||
func (s *sliceS) SelectFrom(interfaces ...interface{}) [][]interface{} {
|
||||
if s.vs != nil {
|
||||
values = s.vs.SelectFrom(values...)
|
||||
interfaces = s.vs.SelectFrom(interfaces...)
|
||||
}
|
||||
|
||||
slices := [][]interface{}{}
|
||||
for _, value := range values {
|
||||
for _, value := range interfaces {
|
||||
slice, ok := value.([]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
|
|
@ -89,24 +89,24 @@ func (s *sliceS) SelectFrom(values ...interface{}) [][]interface{} {
|
|||
return slices
|
||||
}
|
||||
|
||||
func (s *sliceS) At(index int) ValueS {
|
||||
func (s *sliceS) At(index int) InterfaceS {
|
||||
return s.AtP(p.NumberEqual(float64(index)))
|
||||
}
|
||||
|
||||
func (s *sliceS) AtP(predicates ...p.Number) ValueS {
|
||||
func (s *sliceS) AtP(predicates ...p.Number) InterfaceS {
|
||||
return filterSlice(s, sliceAtPFilter{ip: p.NumberAnd(predicates...)})
|
||||
}
|
||||
|
||||
func (s *sliceS) Last() ValueS {
|
||||
func (s *sliceS) Last() InterfaceS {
|
||||
return filterSlice(s, sliceLastFilter{})
|
||||
}
|
||||
|
||||
func (s *sliceS) Children() ValueS {
|
||||
func (s *sliceS) Children() InterfaceS {
|
||||
// No predicates means select all direct children.
|
||||
return s.AtP()
|
||||
}
|
||||
|
||||
func (s *sliceS) All() ValueS {
|
||||
func (s *sliceS) All() InterfaceS {
|
||||
return filterSlice(s, sliceAllFilter{})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ import (
|
|||
// possible) and filters those strings based on the "filtered"
|
||||
// predicates.
|
||||
type StringS interface {
|
||||
// StringS can be used as a Value predicate. If the selector can't
|
||||
// StringS can be used as a Interface predicate. If the selector can't
|
||||
// select any string from the value, then the predicate is
|
||||
// false.
|
||||
p.Value
|
||||
p.Interface
|
||||
|
||||
// SelectFrom finds strings from values using this selector. The
|
||||
// list can be bigger or smaller than the initial lists,
|
||||
|
|
@ -40,7 +40,7 @@ type StringS interface {
|
|||
}
|
||||
|
||||
type stringS struct {
|
||||
vs ValueS
|
||||
vs InterfaceS
|
||||
sp p.String
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ func TestStringSPredicate(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestStringSFromValueS(t *testing.T) {
|
||||
func TestStringSFromInterfaceS(t *testing.T) {
|
||||
if !Children().String().Filter(p.StringLength(p.NumberEqual(4))).Match([]interface{}{"four", "five"}) {
|
||||
t.Fatal("SelectFromor should find element that match")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue