Browse Source

Added Set thingy.

Douglas Thrift 10 years ago
parent
commit
d0bfe64146
2 changed files with 69 additions and 12 deletions
  1. 44 0
      lib/machine_tag/set.rb
  2. 25 12
      lib/machine_tag/tag.rb

+ 44 - 0
lib/machine_tag/set.rb

@@ -21,3 +21,47 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+require 'set'
+
+module MachineTag
+  # Set of tags which can be machine tags.
+  #
+  class Set < ::Set
+    def initialize(enum = nil, &block)
+      @tags_by_namespace = {}
+      @tags_by_namespace_and_predicate = {}
+      super
+    end
+
+    def add(tag)
+      tag = Tag.new(tag) unless tag.is_a? Tag
+      super(tag)
+
+      if tag.machine_tag?
+        @tags_by_namespace[tag.namespace] ||= ::Set.new
+        @tags_by_namespace[tag.namespace] << tag
+        @tags_by_namespace_and_predicate[tag.namespace_and_predicate] ||= ::Set.new
+        @tags_by_namespace_and_predicate[tag.namespace_and_predicate] << tag
+      end
+    end
+
+    def [](namespace_or_namespace_and_predicate, predicate = nil)
+      if namespace_or_namespace_and_predicate =~ /^#{PREFIX}$/
+        namespace = namespace_or_namespace_and_predicate
+
+        unless predicate
+          @tags_by_namespace[namespace]
+        else
+          raise ArgumentError, "Invalid machine tag predicate: #{predicate.inspect}" unless predicate =~ /^#{PREFIX}$/
+          @tags_by_namespace_and_predicate["#{namespace}:#{predicate}"]
+        end
+      elsif namespace_or_namespace_and_predicate =~ /^#{NAMESPACE_AND_PREDICATE}$/
+        namespace_and_predicate = namespace_or_namespace_and_predicate
+        raise ArgumentError, "Separate predicate passed with namespace and predicate: #{namespace_and_predicate.inspect}, #{predicate.inspect}" if predicate
+        @tags_by_namespace_and_predicate[namespace_and_predicate]
+      else
+        raise ArgumentError, "Invalid machine tag namespace and/or predicate: #{namespace_or_namespace_and_predicate.inspect}, #{predicate.inspect}"
+      end
+    end
+  end
+end

+ 25 - 12
lib/machine_tag/tag.rb

@@ -22,21 +22,27 @@
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 module MachineTag
-  # A tag which can be a machine tag.
+  # The regular expression for matching the individual namespace and predicate portions of a machine tag
   #
-  class Tag < String
-    # The regular expression for matching the namespace and predicate portions of a machine tag
-    #
-    # @return [Regexp] the regular expression for matching the namespace and predicate portions of a machine tag
-    #
-    PREFIX = /[a-z][a-z0-9_]*/i
+  # @return [Regexp] the regular expression for matching the individual namespace and predicate portions of a machine tag
+  #
+  PREFIX = /[a-z][a-z0-9_]*/i
 
-    # The regular expression for matching a machine tag
-    #
-    # @return [Regexp] the regular expression for matching a machine tag
-    #
-    MACHINE_TAG = /^(?<namespace>#{PREFIX}):(?<predicate>#{PREFIX})=(?<value>.*)$/
+  # The regular expression for matching the namespace and predicate portion of a machine tag
+  #
+  # @return [Regexp] the regular expression for matching the namespace and predicate portion of a machine tag
+  #
+  NAMESPACE_AND_PREDICATE = /(?<namespace>#{PREFIX}):(?<predicate>#{PREFIX})/
 
+  # The regular expression for matching a machine tag
+  #
+  # @return [Regexp] the regular expression for matching a machine tag
+  #
+  MACHINE_TAG = /^(?<namespace_and_predicate>#{NAMESPACE_AND_PREDICATE})=(?<value>.*)$/
+
+  # A tag which can be a machine tag.
+  #
+  class Tag < String
     # The namespace portion of the machine tag, +nil+ if the tag is not a machine tag
     #
     # @return [String, nil] the namespace portion of the machine tag, +nil+ if the tag is not a machine tag
@@ -49,6 +55,12 @@ module MachineTag
     #
     attr_reader :predicate
 
+    # The namespace and predicate portion of the machine tag, +nil+ if the tag is not a machine tag
+    #
+    # @return [String, nil] the namespace and predicate portion of the machine tag, +nil+ if the tag is not a machine tag
+    #
+    attr_reader :namespace_and_predicate
+
     # The value portion of the machine tag, +nil+ if the tag is not a machine tag
     #
     # @return [String, nil] the value portion of the machine tag is not a machine tag
@@ -62,6 +74,7 @@ module MachineTag
     def initialize(str)
       super
       if match = self.match(MACHINE_TAG)
+        @namespace_and_predicate = match[:namespace_and_predicate]
         @namespace = match[:namespace]
         @predicate = match[:predicate]
         @value = match[:value]