summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/goamz/goamz/ec2/ec2test/filter.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/goamz/goamz/ec2/ec2test/filter.go')
-rw-r--r--vendor/github.com/goamz/goamz/ec2/ec2test/filter.go84
1 files changed, 84 insertions, 0 deletions
diff --git a/vendor/github.com/goamz/goamz/ec2/ec2test/filter.go b/vendor/github.com/goamz/goamz/ec2/ec2test/filter.go
new file mode 100644
index 000000000..1a0c04619
--- /dev/null
+++ b/vendor/github.com/goamz/goamz/ec2/ec2test/filter.go
@@ -0,0 +1,84 @@
+package ec2test
+
+import (
+ "fmt"
+ "net/url"
+ "strings"
+)
+
+// filter holds an ec2 filter. A filter maps an attribute to a set of
+// possible values for that attribute. For an item to pass through the
+// filter, every attribute of the item mentioned in the filter must match
+// at least one of its given values.
+type filter map[string][]string
+
+// newFilter creates a new filter from the Filter fields in the url form.
+//
+// The filtering is specified through a map of name=>values, where the
+// name is a well-defined key identifying the data to be matched,
+// and the list of values holds the possible values the filtered
+// item can take for the key to be included in the
+// result set. For example:
+//
+// Filter.1.Name=instance-type
+// Filter.1.Value.1=m1.small
+// Filter.1.Value.2=m1.large
+//
+func newFilter(form url.Values) filter {
+ // TODO return an error if the fields are not well formed?
+ names := make(map[int]string)
+ values := make(map[int][]string)
+ maxId := 0
+ for name, fvalues := range form {
+ var rest string
+ var id int
+ if x, _ := fmt.Sscanf(name, "Filter.%d.%s", &id, &rest); x != 2 {
+ continue
+ }
+ if id > maxId {
+ maxId = id
+ }
+ if rest == "Name" {
+ names[id] = fvalues[0]
+ continue
+ }
+ if !strings.HasPrefix(rest, "Value.") {
+ continue
+ }
+ values[id] = append(values[id], fvalues[0])
+ }
+
+ f := make(filter)
+ for id, name := range names {
+ f[name] = values[id]
+ }
+ return f
+}
+
+func notDigit(r rune) bool {
+ return r < '0' || r > '9'
+}
+
+// filterable represents an object that can be passed through a filter.
+type filterable interface {
+ // matchAttr returns true if given attribute of the
+ // object matches value. It returns an error if the
+ // attribute is not recognised or the value is malformed.
+ matchAttr(attr, value string) (bool, error)
+}
+
+// ok returns true if x passes through the filter.
+func (f filter) ok(x filterable) (bool, error) {
+next:
+ for a, vs := range f {
+ for _, v := range vs {
+ if ok, err := x.matchAttr(a, v); ok {
+ continue next
+ } else if err != nil {
+ return false, fmt.Errorf("bad attribute or value %q=%q for type %T: %v", a, v, x, err)
+ }
+ }
+ return false, nil
+ }
+ return true, nil
+}