tag.rb 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. module MachineTag
  2. # A tag which can be a machine tag.
  3. #
  4. class Tag < String
  5. PREFIX = /[a-z][a-z0-9_]*/i
  6. # The regular expression for matching a machine tag
  7. #
  8. # @return [Regexp] the regular expression for matching a machine tag
  9. MACHINE_TAG = /^(?<namespace>#{PREFIX}):(?<predicate>#{PREFIX})=(?<value>.*)$/
  10. # The namespace portion of the machine tag, +nil+ if the tag is not a machine tag
  11. #
  12. # @return [String, nil] the namespace portion of the machine tag, +nil+ if the tag is not a machine tag
  13. #
  14. attr_reader :namespace
  15. # The predicate portion of the machine tag, +nil+ if the tag is not a machine tag
  16. #
  17. # @return [String, nil] the predicate portion of the machine tag, +nil+ if the tag is not a machine tag
  18. #
  19. attr_reader :predicate
  20. # The value portion of the machine tag, +nil+ if the tag is not a machine tag
  21. #
  22. # @return [String, nil] the value portion of the machine tag is not a machine tag
  23. #
  24. attr_reader :value
  25. # Creates a tag object which can be a machine tag.
  26. #
  27. # @param str [String] the tag string
  28. #
  29. def initialize(str)
  30. super
  31. if match = self.match(MACHINE_TAG)
  32. @namespace = match[:namespace]
  33. @predicate = match[:predicate]
  34. @value = match[:value]
  35. @value = $1 if @value =~ /^"(.*)"$/
  36. end
  37. end
  38. # Creates a machine tag from a given namespace, predicate, and value.
  39. #
  40. # @param namespace [String] the namespace
  41. # @param predicate [String] the predicate
  42. # @param value [String, Array, #to_s] the value
  43. #
  44. # @option options [String] :separator (',') the separator to use when +value+ is an +Array+
  45. #
  46. # @return [Tag] the machine tag
  47. #
  48. def self.machine_tag(namespace, predicate, value, options = {})
  49. raise ArgumentError, "Invalid machine tag namespace: #{namespace.inspect}" unless namespace =~ /^#{PREFIX}$/
  50. raise ArgumentError, "Invalid machine tag predicate: #{predicate.inspect}" unless predicate =~ /^#{PREFIX}$/
  51. options[:separator] ||= ','
  52. case value
  53. when Array
  54. new("#{namespace}:#{predicate}=#{value.join(options[:separator])}")
  55. else
  56. new("#{namespace}:#{predicate}=#{value}")
  57. end
  58. end
  59. # Returns whether this tag is a machine tag or not.
  60. #
  61. # @return [Boolean] +true+ if this tag is a machine tag, otherwise +false+
  62. #
  63. def machine_tag?
  64. !!namespace
  65. end
  66. end
  67. end