github.com/timstclair/heapster@v0.20.0-alpha1/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  // ParseSelector takes a string representing a selector and returns an
   185  // object suitable for matching, or an error.
   186  func ParseSelector(selector string) (Selector, error) {
   187  	return parseSelector(selector,
   188  		func(lhs, rhs string) (newLhs, newRhs string, err error) {
   189  			return lhs, rhs, nil
   190  		})
   191  }
   192  
   193  // Parses the selector and runs them through the given TransformFunc.
   194  func ParseAndTransformSelector(selector string, fn TransformFunc) (Selector, error) {
   195  	return parseSelector(selector, fn)
   196  }
   197  
   198  // Function to transform selectors.
   199  type TransformFunc func(field, value string) (newField, newValue string, err error)
   200  
   201  func try(selectorPiece, op string) (lhs, rhs string, ok bool) {
   202  	pieces := strings.Split(selectorPiece, op)
   203  	if len(pieces) == 2 {
   204  		return pieces[0], pieces[1], true
   205  	}
   206  	return "", "", false
   207  }
   208  
   209  func parseSelector(selector string, fn TransformFunc) (Selector, error) {
   210  	parts := strings.Split(selector, ",")
   211  	sort.StringSlice(parts).Sort()
   212  	var items []Selector
   213  	for _, part := range parts {
   214  		if part == "" {
   215  			continue
   216  		}
   217  		if lhs, rhs, ok := try(part, "!="); ok {
   218  			items = append(items, &notHasTerm{field: lhs, value: rhs})
   219  		} else if lhs, rhs, ok := try(part, "=="); ok {
   220  			items = append(items, &hasTerm{field: lhs, value: rhs})
   221  		} else if lhs, rhs, ok := try(part, "="); ok {
   222  			items = append(items, &hasTerm{field: lhs, value: rhs})
   223  		} else {
   224  			return nil, fmt.Errorf("invalid selector: '%s'; can't understand '%s'", selector, part)
   225  		}
   226  	}
   227  	if len(items) == 1 {
   228  		return items[0].Transform(fn)
   229  	}
   230  	return andTerm(items).Transform(fn)
   231  }
   232  
   233  // OneTermEqualSelector returns an object that matches objects where one field/field equals one value.
   234  // Cannot return an error.
   235  func OneTermEqualSelector(k, v string) Selector {
   236  	return &hasTerm{field: k, value: v}
   237  }