github.com/aclisp/heapster@v0.19.2-0.20160613100040-51756f899a96/Godeps/_workspace/src/k8s.io/kubernetes/pkg/fields/selector.go (about)

     1  /*
     2  Copyright 2015 The Kubernetes Authors All rights reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package fields
    18  
    19  import (
    20  	"fmt"
    21  	"sort"
    22  	"strings"
    23  )
    24  
    25  // Selector represents a field selector.
    26  type Selector interface {
    27  	// Matches returns true if this selector matches the given set of fields.
    28  	Matches(Fields) bool
    29  
    30  	// Empty returns true if this selector does not restrict the selection space.
    31  	Empty() bool
    32  
    33  	// RequiresExactMatch allows a caller to introspect whether a given selector
    34  	// requires a single specific field to be set, and if so returns the value it
    35  	// requires.
    36  	RequiresExactMatch(field string) (value string, found bool)
    37  
    38  	// Transform returns a new copy of the selector after TransformFunc has been
    39  	// applied to the entire selector, or an error if fn returns an error.
    40  	Transform(fn TransformFunc) (Selector, error)
    41  
    42  	// String returns a human readable string that represents this selector.
    43  	String() string
    44  }
    45  
    46  // Everything returns a selector that matches all fields.
    47  func Everything() Selector {
    48  	return andTerm{}
    49  }
    50  
    51  type hasTerm struct {
    52  	field, value string
    53  }
    54  
    55  func (t *hasTerm) Matches(ls Fields) bool {
    56  	return ls.Get(t.field) == t.value
    57  }
    58  
    59  func (t *hasTerm) Empty() bool {
    60  	return false
    61  }
    62  
    63  func (t *hasTerm) RequiresExactMatch(field string) (value string, found bool) {
    64  	if t.field == field {
    65  		return t.value, true
    66  	}
    67  	return "", false
    68  }
    69  
    70  func (t *hasTerm) Transform(fn TransformFunc) (Selector, error) {
    71  	field, value, err := fn(t.field, t.value)
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  	return &hasTerm{field, value}, nil
    76  }
    77  
    78  func (t *hasTerm) String() string {
    79  	return fmt.Sprintf("%v=%v", t.field, t.value)
    80  }
    81  
    82  type notHasTerm struct {
    83  	field, value string
    84  }
    85  
    86  func (t *notHasTerm) Matches(ls Fields) bool {
    87  	return ls.Get(t.field) != t.value
    88  }
    89  
    90  func (t *notHasTerm) Empty() bool {
    91  	return false
    92  }
    93  
    94  func (t *notHasTerm) RequiresExactMatch(field string) (value string, found bool) {
    95  	return "", false
    96  }
    97  
    98  func (t *notHasTerm) Transform(fn TransformFunc) (Selector, error) {
    99  	field, value, err := fn(t.field, t.value)
   100  	if err != nil {
   101  		return nil, err
   102  	}
   103  	return &notHasTerm{field, value}, nil
   104  }
   105  
   106  func (t *notHasTerm) String() string {
   107  	return fmt.Sprintf("%v!=%v", t.field, t.value)
   108  }
   109  
   110  type andTerm []Selector
   111  
   112  func (t andTerm) Matches(ls Fields) bool {
   113  	for _, q := range t {
   114  		if !q.Matches(ls) {
   115  			return false
   116  		}
   117  	}
   118  	return true
   119  }
   120  
   121  func (t andTerm) Empty() bool {
   122  	if t == nil {
   123  		return true
   124  	}
   125  	if len([]Selector(t)) == 0 {
   126  		return true
   127  	}
   128  	for i := range t {
   129  		if !t[i].Empty() {
   130  			return false
   131  		}
   132  	}
   133  	return true
   134  }
   135  
   136  func (t andTerm) RequiresExactMatch(field string) (string, bool) {
   137  	if t == nil || len([]Selector(t)) == 0 {
   138  		return "", false
   139  	}
   140  	for i := range t {
   141  		if value, found := t[i].RequiresExactMatch(field); found {
   142  			return value, found
   143  		}
   144  	}
   145  	return "", false
   146  }
   147  
   148  func (t andTerm) Transform(fn TransformFunc) (Selector, error) {
   149  	next := make([]Selector, len([]Selector(t)))
   150  	for i, s := range []Selector(t) {
   151  		n, err := s.Transform(fn)
   152  		if err != nil {
   153  			return nil, err
   154  		}
   155  		next[i] = n
   156  	}
   157  	return andTerm(next), nil
   158  }
   159  
   160  func (t andTerm) String() string {
   161  	var terms []string
   162  	for _, q := range t {
   163  		terms = append(terms, q.String())
   164  	}
   165  	return strings.Join(terms, ",")
   166  }
   167  
   168  // SelectorFromSet returns a Selector which will match exactly the given Set. A
   169  // nil Set is considered equivalent to Everything().
   170  func SelectorFromSet(ls Set) Selector {
   171  	if ls == nil {
   172  		return Everything()
   173  	}
   174  	items := make([]Selector, 0, len(ls))
   175  	for field, value := range ls {
   176  		items = append(items, &hasTerm{field: field, value: value})
   177  	}
   178  	if len(items) == 1 {
   179  		return items[0]
   180  	}
   181  	return andTerm(items)
   182  }
   183  
   184  // ParseSelectorOrDie takes a string representing a selector and returns an
   185  // object suitable for matching, or panic when an error occur.
   186  func ParseSelectorOrDie(s string) Selector {
   187  	selector, err := ParseSelector(s)
   188  	if err != nil {
   189  		panic(err)
   190  	}
   191  	return selector
   192  }
   193  
   194  // ParseSelector takes a string representing a selector and returns an
   195  // object suitable for matching, or an error.
   196  func ParseSelector(selector string) (Selector, error) {
   197  	return parseSelector(selector,
   198  		func(lhs, rhs string) (newLhs, newRhs string, err error) {
   199  			return lhs, rhs, nil
   200  		})
   201  }
   202  
   203  // Parses the selector and runs them through the given TransformFunc.
   204  func ParseAndTransformSelector(selector string, fn TransformFunc) (Selector, error) {
   205  	return parseSelector(selector, fn)
   206  }
   207  
   208  // Function to transform selectors.
   209  type TransformFunc func(field, value string) (newField, newValue string, err error)
   210  
   211  func try(selectorPiece, op string) (lhs, rhs string, ok bool) {
   212  	pieces := strings.Split(selectorPiece, op)
   213  	if len(pieces) == 2 {
   214  		return pieces[0], pieces[1], true
   215  	}
   216  	return "", "", false
   217  }
   218  
   219  func parseSelector(selector string, fn TransformFunc) (Selector, error) {
   220  	parts := strings.Split(selector, ",")
   221  	sort.StringSlice(parts).Sort()
   222  	var items []Selector
   223  	for _, part := range parts {
   224  		if part == "" {
   225  			continue
   226  		}
   227  		if lhs, rhs, ok := try(part, "!="); ok {
   228  			items = append(items, &notHasTerm{field: lhs, value: rhs})
   229  		} else if lhs, rhs, ok := try(part, "=="); ok {
   230  			items = append(items, &hasTerm{field: lhs, value: rhs})
   231  		} else if lhs, rhs, ok := try(part, "="); ok {
   232  			items = append(items, &hasTerm{field: lhs, value: rhs})
   233  		} else {
   234  			return nil, fmt.Errorf("invalid selector: '%s'; can't understand '%s'", selector, part)
   235  		}
   236  	}
   237  	if len(items) == 1 {
   238  		return items[0].Transform(fn)
   239  	}
   240  	return andTerm(items).Transform(fn)
   241  }
   242  
   243  // OneTermEqualSelector returns an object that matches objects where one field/field equals one value.
   244  // Cannot return an error.
   245  func OneTermEqualSelector(k, v string) Selector {
   246  	return &hasTerm{field: k, value: v}
   247  }