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"
|
p "k8s.io/kubectl/pkg/framework/predicates"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A valueFilter allows us to chain ValueS to ValueS. None of this is
|
// A interfaceFilter allows us to chain InterfaceS to InterfaceS. None of this is
|
||||||
// public. It's implementing the "SelectFrom" part of a ValueS.
|
// public. It's implementing the "SelectFrom" part of a InterfaceS.
|
||||||
type valueFilter interface {
|
type interfaceFilter interface {
|
||||||
SelectFrom(...interface{}) []interface{}
|
SelectFrom(...interface{}) []interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// valueFilterP filters using a predicate.
|
// interfaceFilterP filters using a predicate.
|
||||||
type valueFilterP struct {
|
type interfaceFilterP struct {
|
||||||
vp p.Value
|
vp p.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *valueFilterP) SelectFrom(values ...interface{}) []interface{} {
|
func (f *interfaceFilterP) SelectFrom(interfaces ...interface{}) []interface{} {
|
||||||
vs := []interface{}{}
|
vs := []interface{}{}
|
||||||
for _, value := range values {
|
for _, value := range interfaces {
|
||||||
if f.vp.Match(value) {
|
if f.vp.Match(value) {
|
||||||
vs = append(vs, value)
|
vs = append(vs, value)
|
||||||
}
|
}
|
||||||
|
|
@ -41,13 +41,13 @@ func (f *valueFilterP) SelectFrom(values ...interface{}) []interface{} {
|
||||||
return vs
|
return vs
|
||||||
}
|
}
|
||||||
|
|
||||||
type valueChildrenFilter struct{}
|
type interfaceChildrenFilter struct{}
|
||||||
|
|
||||||
func (valueChildrenFilter) SelectFrom(values ...interface{}) []interface{} {
|
func (interfaceChildrenFilter) SelectFrom(interfaces ...interface{}) []interface{} {
|
||||||
children := []interface{}{}
|
children := []interface{}{}
|
||||||
// We could process all slices and then all maps, but we want to
|
// We could process all slices and then all maps, but we want to
|
||||||
// keep things in the same order.
|
// keep things in the same order.
|
||||||
for _, value := range values {
|
for _, value := range interfaces {
|
||||||
// Only one of the two should do something useful.
|
// Only one of the two should do something useful.
|
||||||
children = append(children, Slice().Children().SelectFrom(value)...)
|
children = append(children, Slice().Children().SelectFrom(value)...)
|
||||||
children = append(children, Map().Children().SelectFrom(value)...)
|
children = append(children, Map().Children().SelectFrom(value)...)
|
||||||
|
|
@ -55,33 +55,33 @@ func (valueChildrenFilter) SelectFrom(values ...interface{}) []interface{} {
|
||||||
return children
|
return children
|
||||||
}
|
}
|
||||||
|
|
||||||
// valueSliceFilter is a Value-to-Slice combined with a Slice-to-Value
|
// interfaceSliceFilter is a Interface-to-Slice combined with a Slice-to-Interface
|
||||||
// to form a Value-to-Value.
|
// to form a Interface-to-Interface.
|
||||||
type valueSliceFilter struct {
|
type interfaceSliceFilter struct {
|
||||||
ss SliceS
|
ss SliceS
|
||||||
sf sliceFilter
|
sf sliceFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *valueSliceFilter) SelectFrom(values ...interface{}) []interface{} {
|
func (s *interfaceSliceFilter) SelectFrom(interfaces ...interface{}) []interface{} {
|
||||||
return s.sf.SelectFrom(s.ss.SelectFrom(values...)...)
|
return s.sf.SelectFrom(s.ss.SelectFrom(interfaces...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// valueMapFilter is a Value-to-Map combined with a Map-to-Value to form
|
// interfaceMapFilter is a Interface-to-Map combined with a Map-to-Interface to form
|
||||||
// a Value-to-Value.
|
// a Interface-to-Interface.
|
||||||
type valueMapFilter struct {
|
type interfaceMapFilter struct {
|
||||||
ms MapS
|
ms MapS
|
||||||
mf mapFilter
|
mf mapFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *valueMapFilter) SelectFrom(values ...interface{}) []interface{} {
|
func (s *interfaceMapFilter) SelectFrom(interfaces ...interface{}) []interface{} {
|
||||||
return s.mf.SelectFrom(s.ms.SelectFrom(values...)...)
|
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{}{}
|
vs := []interface{}{}
|
||||||
for _, value := range values {
|
for _, value := range interfaces {
|
||||||
vs = append(vs, value)
|
vs = append(vs, value)
|
||||||
// Only one of the follow two statements should return something ...
|
// Only one of the follow two statements should return something ...
|
||||||
vs = append(vs, Slice().All().SelectFrom(value)...)
|
vs = append(vs, Slice().All().SelectFrom(value)...)
|
||||||
|
|
@ -20,15 +20,15 @@ import (
|
||||||
p "k8s.io/kubectl/pkg/framework/predicates"
|
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.
|
// "filtered" predicates.
|
||||||
type ValueS interface {
|
type InterfaceS interface {
|
||||||
// ValueS can be used as a Value predicate. If the selector can't
|
// InterfaceS can be used as a Interface predicate. If the selector can't
|
||||||
// select any value from the value, then the predicate is
|
// select any interface from the interface, then the predicate is
|
||||||
// false.
|
// 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,
|
// list can be bigger or smaller than the initial lists,
|
||||||
// depending on the select criterias.
|
// depending on the select criterias.
|
||||||
SelectFrom(...interface{}) []interface{}
|
SelectFrom(...interface{}) []interface{}
|
||||||
|
|
@ -46,75 +46,75 @@ type ValueS interface {
|
||||||
|
|
||||||
// Children returns a selector that selects the direct children
|
// Children returns a selector that selects the direct children
|
||||||
// of the given values.
|
// of the given values.
|
||||||
Children() ValueS
|
Children() InterfaceS
|
||||||
// All returns a selector that selects all direct and indrect
|
// All returns a selector that selects all direct and indrect
|
||||||
// children of the given values.
|
// children of the given values.
|
||||||
All() ValueS
|
All() InterfaceS
|
||||||
|
|
||||||
// Filter will create a new StringS that filters only the values
|
// Filter will create a new StringS that filters only the values
|
||||||
// who match the predicate.
|
// who match the predicate.
|
||||||
Filter(...p.Value) ValueS
|
Filter(...p.Interface) InterfaceS
|
||||||
}
|
}
|
||||||
|
|
||||||
// Children selects all the children of the values.
|
// Children selects all the children of the values.
|
||||||
func Children() ValueS {
|
func Children() InterfaceS {
|
||||||
return &valueS{vf: valueChildrenFilter{}}
|
return &interfaceS{vf: interfaceChildrenFilter{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// All selects all the direct and indirect childrens of the values.
|
// All selects all the direct and indirect childrens of the values.
|
||||||
func All() ValueS {
|
func All() InterfaceS {
|
||||||
return &valueS{vf: valueAllFilter{}}
|
return &interfaceS{vf: interfaceAllFilter{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter will only return the values that match the predicate.
|
// Filter will only return the values that match the predicate.
|
||||||
func Filter(predicates ...p.Value) ValueS {
|
func Filter(predicates ...p.Interface) InterfaceS {
|
||||||
return &valueS{vf: &valueFilterP{vp: p.ValueAnd(predicates...)}}
|
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.
|
// slices, strings, integer from a list of values.
|
||||||
type valueS struct {
|
type interfaceS struct {
|
||||||
vs ValueS
|
vs InterfaceS
|
||||||
vf valueFilter
|
vf interfaceFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match returns true if the selector can find items in the given
|
// Match returns true if the selector can find items in the given
|
||||||
// value. Otherwise, it returns false.
|
// 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
|
return len(s.SelectFrom(value)) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *valueS) SelectFrom(values ...interface{}) []interface{} {
|
func (s *interfaceS) SelectFrom(interfaces ...interface{}) []interface{} {
|
||||||
if s.vs != nil {
|
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}
|
return &mapS{vs: s}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *valueS) Slice() SliceS {
|
func (s *interfaceS) Slice() SliceS {
|
||||||
return &sliceS{vs: s}
|
return &sliceS{vs: s}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *valueS) Number() NumberS {
|
func (s *interfaceS) Number() NumberS {
|
||||||
return &numberS{vs: s}
|
return &numberS{vs: s}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *valueS) String() StringS {
|
func (s *interfaceS) String() StringS {
|
||||||
return &stringS{vs: s}
|
return &stringS{vs: s}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *valueS) Children() ValueS {
|
func (s *interfaceS) Children() InterfaceS {
|
||||||
return &valueS{vs: s, vf: valueChildrenFilter{}}
|
return &interfaceS{vs: s, vf: interfaceChildrenFilter{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *valueS) All() ValueS {
|
func (s *interfaceS) All() InterfaceS {
|
||||||
return &valueS{vs: s, vf: valueAllFilter{}}
|
return &interfaceS{vs: s, vf: interfaceAllFilter{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *valueS) Filter(predicates ...p.Value) ValueS {
|
func (s *interfaceS) Filter(predicates ...p.Interface) InterfaceS {
|
||||||
return &valueS{vs: s, vf: &valueFilterP{vp: p.ValueAnd(predicates...)}}
|
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{}{}) {
|
if !unstructpath.Slice().Match([]interface{}{}) {
|
||||||
t.Fatal("SelectFroming a slice from a slice should match.")
|
t.Fatal("SelectFroming a slice from a slice should match.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValueSMap(t *testing.T) {
|
func TestInterfaceSMap(t *testing.T) {
|
||||||
root := map[string]interface{}{
|
root := map[string]interface{}{
|
||||||
"key1": "value",
|
"key1": "value",
|
||||||
"key2": 1,
|
"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{}{
|
root := map[string]interface{}{
|
||||||
"key1": "value",
|
"key1": "value",
|
||||||
"key2": 1,
|
"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{}{
|
root := map[string]interface{}{
|
||||||
"key1": "value",
|
"key1": "value",
|
||||||
"key2": 1,
|
"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{}{}}
|
u := []interface{}{1., 2., "three", 4., 5., []interface{}{}}
|
||||||
|
|
||||||
numbers := unstructpath.Children().Number().SelectFrom(u)
|
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{}{
|
root := map[string]interface{}{
|
||||||
"key1": "value",
|
"key1": "value",
|
||||||
"key2": 1,
|
"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{}{
|
root := map[string]interface{}{
|
||||||
"key1": "value",
|
"key1": "value",
|
||||||
"key2": 1,
|
"key2": 1,
|
||||||
|
|
@ -22,14 +22,14 @@ import (
|
||||||
p "k8s.io/kubectl/pkg/framework/predicates"
|
p "k8s.io/kubectl/pkg/framework/predicates"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is a Map-to-Value filter.
|
// This is a Map-to-Interface filter.
|
||||||
type mapFilter interface {
|
type mapFilter interface {
|
||||||
SelectFrom(...map[string]interface{}) []interface{}
|
SelectFrom(...map[string]interface{}) []interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func filterMap(ms MapS, mf mapFilter) ValueS {
|
func filterMap(ms MapS, mf mapFilter) InterfaceS {
|
||||||
return &valueS{
|
return &interfaceS{
|
||||||
vf: &valueMapFilter{
|
vf: &interfaceMapFilter{
|
||||||
ms: ms,
|
ms: ms,
|
||||||
mf: mf,
|
mf: mf,
|
||||||
},
|
},
|
||||||
|
|
@ -41,29 +41,29 @@ type mapFieldPFilter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f mapFieldPFilter) SelectFrom(maps ...map[string]interface{}) []interface{} {
|
func (f mapFieldPFilter) SelectFrom(maps ...map[string]interface{}) []interface{} {
|
||||||
values := []interface{}{}
|
interfaces := []interface{}{}
|
||||||
|
|
||||||
for _, m := range maps {
|
for _, m := range maps {
|
||||||
for _, field := range sortedKeys(m) {
|
for _, field := range sortedKeys(m) {
|
||||||
if !f.sp.Match(field) {
|
if !f.sp.Match(field) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
values = append(values, m[field])
|
interfaces = append(interfaces, m[field])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values
|
return interfaces
|
||||||
}
|
}
|
||||||
|
|
||||||
type mapAllFilter struct{}
|
type mapAllFilter struct{}
|
||||||
|
|
||||||
func (mapAllFilter) SelectFrom(maps ...map[string]interface{}) []interface{} {
|
func (mapAllFilter) SelectFrom(maps ...map[string]interface{}) []interface{} {
|
||||||
values := []interface{}{}
|
interfaces := []interface{}{}
|
||||||
for _, m := range maps {
|
for _, m := range maps {
|
||||||
for _, field := range sortedKeys(m) {
|
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 {
|
func sortedKeys(m map[string]interface{}) []string {
|
||||||
|
|
|
||||||
|
|
@ -20,60 +20,60 @@ import (
|
||||||
p "k8s.io/kubectl/pkg/framework/predicates"
|
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"
|
// possible) and filters those maps based on the "filtered"
|
||||||
// predicates.
|
// predicates.
|
||||||
type MapS interface {
|
type MapS interface {
|
||||||
// MapS can be used as a Value predicate. If the selector can't
|
// MapS can be used as a Interface predicate. If the selector can't
|
||||||
// select any map from the value, then the predicate is
|
// select any map from the interface, then the predicate is
|
||||||
// false.
|
// 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,
|
// list can be bigger or smaller than the initial lists,
|
||||||
// depending on the select criterias.
|
// depending on the select criterias.
|
||||||
SelectFrom(...interface{}) []map[string]interface{}
|
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
|
// map. If the field doesn't exist, the value will be filtered
|
||||||
// out.
|
// out.
|
||||||
Field(string) ValueS
|
Field(string) InterfaceS
|
||||||
// FieldP returns all the values pointed by field that match the
|
// FieldP returns all the interfaces pointed by field that match the
|
||||||
// string predicate. This selector can return more values than
|
// string predicate. This selector can return more values than
|
||||||
// it gets (for one map, it can returns multiple sub-values, one
|
// it gets (for one map, it can returns multiple sub-values, one
|
||||||
// for each field that matches the predicate).
|
// 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
|
// All returns a selector that selects all direct and indrect
|
||||||
// children of the given values.
|
// children of the given values.
|
||||||
Children() ValueS
|
Children() InterfaceS
|
||||||
// All returns a selector that selects all direct and indrect
|
// All returns a selector that selects all direct and indrect
|
||||||
// children of the given values.
|
// children of the given values.
|
||||||
All() ValueS
|
All() InterfaceS
|
||||||
|
|
||||||
// Filter will create a new MapS that filters only the values
|
// Filter will create a new MapS that filters only the values
|
||||||
// who match the predicate.
|
// who match the predicate.
|
||||||
Filter(...p.Map) MapS
|
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.
|
// if possible.
|
||||||
func Map() MapS {
|
func Map() MapS {
|
||||||
return &mapS{}
|
return &mapS{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type mapS struct {
|
type mapS struct {
|
||||||
vs ValueS
|
vs InterfaceS
|
||||||
mp p.Map
|
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 {
|
if s.vs != nil {
|
||||||
values = s.vs.SelectFrom(values...)
|
interfaces = s.vs.SelectFrom(interfaces...)
|
||||||
}
|
}
|
||||||
|
|
||||||
maps := []map[string]interface{}{}
|
maps := []map[string]interface{}{}
|
||||||
for _, value := range values {
|
for _, value := range interfaces {
|
||||||
m, ok := value.(map[string]interface{})
|
m, ok := value.(map[string]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
|
|
@ -87,20 +87,20 @@ func (s *mapS) SelectFrom(values ...interface{}) []map[string]interface{} {
|
||||||
return maps
|
return maps
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *mapS) Field(str string) ValueS {
|
func (s *mapS) Field(str string) InterfaceS {
|
||||||
return s.FieldP(p.StringEqual(str))
|
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...)})
|
return filterMap(s, mapFieldPFilter{sp: p.StringAnd(predicates...)})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *mapS) Children() ValueS {
|
func (s *mapS) Children() InterfaceS {
|
||||||
// No predicate means select all.
|
// No predicate means select all.
|
||||||
return s.FieldP()
|
return s.FieldP()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *mapS) All() ValueS {
|
func (s *mapS) All() InterfaceS {
|
||||||
return filterMap(s, mapAllFilter{})
|
return filterMap(s, mapAllFilter{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,10 @@ import (
|
||||||
// possible) and filters those numbers based on the "filtered"
|
// possible) and filters those numbers based on the "filtered"
|
||||||
// predicates.
|
// predicates.
|
||||||
type NumberS interface {
|
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
|
// select any number from the value, then the predicate is
|
||||||
// false.
|
// false.
|
||||||
p.Value
|
p.Interface
|
||||||
|
|
||||||
// SelectFrom finds numbers from values using this selector. The
|
// SelectFrom finds numbers from values using this selector. The
|
||||||
// list can be bigger or smaller than the initial lists,
|
// list can be bigger or smaller than the initial lists,
|
||||||
|
|
@ -45,7 +45,7 @@ func Number() NumberS {
|
||||||
}
|
}
|
||||||
|
|
||||||
type numberS struct {
|
type numberS struct {
|
||||||
vs ValueS
|
vs InterfaceS
|
||||||
ip p.Number
|
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.}) {
|
if !Children().Number().Filter(p.NumberGreaterThan(10)).Match([]interface{}{1., 2., 5., 12.}) {
|
||||||
t.Fatal("SelectFromor should find element that match")
|
t.Fatal("SelectFromor should find element that match")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,16 +20,16 @@ import (
|
||||||
p "k8s.io/kubectl/pkg/framework/predicates"
|
p "k8s.io/kubectl/pkg/framework/predicates"
|
||||||
)
|
)
|
||||||
|
|
||||||
func filterSlice(ss SliceS, sf sliceFilter) ValueS {
|
func filterSlice(ss SliceS, sf sliceFilter) InterfaceS {
|
||||||
return &valueS{
|
return &interfaceS{
|
||||||
vf: &valueSliceFilter{
|
vf: &interfaceSliceFilter{
|
||||||
ss: ss,
|
ss: ss,
|
||||||
sf: sf,
|
sf: sf,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a Slice-to-Value filter.
|
// This is a Slice-to-Interface filter.
|
||||||
type sliceFilter interface {
|
type sliceFilter interface {
|
||||||
SelectFrom(...[]interface{}) []interface{}
|
SelectFrom(...[]interface{}) []interface{}
|
||||||
}
|
}
|
||||||
|
|
@ -39,40 +39,40 @@ type sliceAtPFilter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f sliceAtPFilter) SelectFrom(slices ...[]interface{}) []interface{} {
|
func (f sliceAtPFilter) SelectFrom(slices ...[]interface{}) []interface{} {
|
||||||
values := []interface{}{}
|
interfaces := []interface{}{}
|
||||||
|
|
||||||
for _, slice := range slices {
|
for _, slice := range slices {
|
||||||
for i := range slice {
|
for i := range slice {
|
||||||
if !f.ip.Match(float64(i)) {
|
if !f.ip.Match(float64(i)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
values = append(values, slice[i])
|
interfaces = append(interfaces, slice[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values
|
return interfaces
|
||||||
}
|
}
|
||||||
|
|
||||||
type sliceLastFilter struct{}
|
type sliceLastFilter struct{}
|
||||||
|
|
||||||
func (f sliceLastFilter) SelectFrom(slices ...[]interface{}) []interface{} {
|
func (f sliceLastFilter) SelectFrom(slices ...[]interface{}) []interface{} {
|
||||||
values := []interface{}{}
|
interfaces := []interface{}{}
|
||||||
for _, slice := range slices {
|
for _, slice := range slices {
|
||||||
if len(slice) == 0 {
|
if len(slice) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
values = append(values, slice[len(slice)-1])
|
interfaces = append(interfaces, slice[len(slice)-1])
|
||||||
}
|
}
|
||||||
return values
|
return interfaces
|
||||||
}
|
}
|
||||||
|
|
||||||
type sliceAllFilter struct{}
|
type sliceAllFilter struct{}
|
||||||
|
|
||||||
func (sliceAllFilter) SelectFrom(slices ...[]interface{}) []interface{} {
|
func (sliceAllFilter) SelectFrom(slices ...[]interface{}) []interface{} {
|
||||||
values := []interface{}{}
|
interfaces := []interface{}{}
|
||||||
for _, slice := range slices {
|
for _, slice := range slices {
|
||||||
for _, v := range slice {
|
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"
|
// possible) and filters those slices based on the "filtered"
|
||||||
// predicates.
|
// predicates.
|
||||||
type SliceS interface {
|
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
|
// can't select any slice from the value, then the predicate is
|
||||||
// false.
|
// false.
|
||||||
p.Value
|
p.Interface
|
||||||
|
|
||||||
// SelectFrom finds slices from values using this selector. The
|
// SelectFrom finds slices from values using this selector. The
|
||||||
// list can be bigger or smaller than the initial lists,
|
// 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
|
// At returns a selector that select the child at the given
|
||||||
// index, if the list has such an index. Otherwise, nothing is
|
// index, if the list has such an index. Otherwise, nothing is
|
||||||
// returned.
|
// returned.
|
||||||
At(index int) ValueS
|
At(index int) InterfaceS
|
||||||
// AtP returns a selector that selects all the item whose index
|
// AtP returns a selector that selects all the item whose index
|
||||||
// matches the number predicate. More predicates can be given,
|
// matches the number predicate. More predicates can be given,
|
||||||
// they are "and"-ed by this method.
|
// 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
|
// Last returns a selector that selects the last value of the
|
||||||
// list. If the list is empty, then nothing will be selected.
|
// 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
|
// All returns a selector that selects all direct and indrect
|
||||||
// children of the given values.
|
// children of the given values.
|
||||||
Children() ValueS
|
Children() InterfaceS
|
||||||
// All returns a selector that selects all direct and indrect
|
// All returns a selector that selects all direct and indrect
|
||||||
// children of the given values.
|
// children of the given values.
|
||||||
All() ValueS
|
All() InterfaceS
|
||||||
|
|
||||||
// Filter will create a new SliceS that filters only the values
|
// Filter will create a new SliceS that filters only the values
|
||||||
// who match the predicate.
|
// who match the predicate.
|
||||||
|
|
@ -65,17 +65,17 @@ func Slice() SliceS {
|
||||||
}
|
}
|
||||||
|
|
||||||
type sliceS struct {
|
type sliceS struct {
|
||||||
vs ValueS
|
vs InterfaceS
|
||||||
sp p.Slice
|
sp p.Slice
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sliceS) SelectFrom(values ...interface{}) [][]interface{} {
|
func (s *sliceS) SelectFrom(interfaces ...interface{}) [][]interface{} {
|
||||||
if s.vs != nil {
|
if s.vs != nil {
|
||||||
values = s.vs.SelectFrom(values...)
|
interfaces = s.vs.SelectFrom(interfaces...)
|
||||||
}
|
}
|
||||||
|
|
||||||
slices := [][]interface{}{}
|
slices := [][]interface{}{}
|
||||||
for _, value := range values {
|
for _, value := range interfaces {
|
||||||
slice, ok := value.([]interface{})
|
slice, ok := value.([]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
|
|
@ -89,24 +89,24 @@ func (s *sliceS) SelectFrom(values ...interface{}) [][]interface{} {
|
||||||
return slices
|
return slices
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sliceS) At(index int) ValueS {
|
func (s *sliceS) At(index int) InterfaceS {
|
||||||
return s.AtP(p.NumberEqual(float64(index)))
|
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...)})
|
return filterSlice(s, sliceAtPFilter{ip: p.NumberAnd(predicates...)})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sliceS) Last() ValueS {
|
func (s *sliceS) Last() InterfaceS {
|
||||||
return filterSlice(s, sliceLastFilter{})
|
return filterSlice(s, sliceLastFilter{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sliceS) Children() ValueS {
|
func (s *sliceS) Children() InterfaceS {
|
||||||
// No predicates means select all direct children.
|
// No predicates means select all direct children.
|
||||||
return s.AtP()
|
return s.AtP()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sliceS) All() ValueS {
|
func (s *sliceS) All() InterfaceS {
|
||||||
return filterSlice(s, sliceAllFilter{})
|
return filterSlice(s, sliceAllFilter{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,10 @@ import (
|
||||||
// possible) and filters those strings based on the "filtered"
|
// possible) and filters those strings based on the "filtered"
|
||||||
// predicates.
|
// predicates.
|
||||||
type StringS interface {
|
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
|
// select any string from the value, then the predicate is
|
||||||
// false.
|
// false.
|
||||||
p.Value
|
p.Interface
|
||||||
|
|
||||||
// SelectFrom finds strings from values using this selector. The
|
// SelectFrom finds strings from values using this selector. The
|
||||||
// list can be bigger or smaller than the initial lists,
|
// list can be bigger or smaller than the initial lists,
|
||||||
|
|
@ -40,7 +40,7 @@ type StringS interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type stringS struct {
|
type stringS struct {
|
||||||
vs ValueS
|
vs InterfaceS
|
||||||
sp p.String
|
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"}) {
|
if !Children().String().Filter(p.StringLength(p.NumberEqual(4))).Match([]interface{}{"four", "five"}) {
|
||||||
t.Fatal("SelectFromor should find element that match")
|
t.Fatal("SelectFromor should find element that match")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue