Merge pull request #360 from apelisse/rename-value-to-interface

predicates: Rename Value into Interface
This commit is contained in:
k8s-ci-robot 2018-03-19 14:45:00 -07:00 committed by GitHub
commit c8107f2ffc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 298 additions and 298 deletions

View File

@ -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...))
}

View File

@ -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}")
}
}

View File

@ -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...))
}

View File

@ -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}")
}
}

View File

@ -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)...)

View File

@ -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...)}}
}

View File

@ -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,

View File

@ -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 {

View File

@ -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{})
}

View File

@ -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
}

View File

@ -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")
}

View File

@ -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
}

View File

@ -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{})
}

View File

@ -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
}

View File

@ -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")
}