Class: JetstreamBridge::Models::Subject
- Inherits:
-
Object
- Object
- JetstreamBridge::Models::Subject
- Defined in:
- lib/jetstream_bridge/models/subject.rb
Overview
Value object representing a NATS subject
Constant Summary collapse
- WILDCARD_SINGLE =
'*'- WILDCARD_MULTI =
'>'- SEPARATOR =
'.'- INVALID_CHARS =
/[#{Regexp.escape(WILDCARD_SINGLE + WILDCARD_MULTI + SEPARATOR)}]/
Instance Attribute Summary collapse
-
#tokens ⇒ Object
readonly
Returns the value of attribute tokens.
-
#value ⇒ Object
readonly
Returns the value of attribute value.
Class Method Summary collapse
- .destination(source:, app_name:) ⇒ Object
- .dlq(app_name:) ⇒ Object
-
.parse(string) ⇒ Subject
Parse a subject string into a Subject object with metadata.
-
.source(app_name:, dest:) ⇒ Object
Factory methods.
-
.subject_matcher ⇒ Object
Lazy-load SubjectMatcher to avoid circular dependency.
-
.validate_component!(value, name) ⇒ Object
Validate a component (env, app_name, etc.) for use in subjects.
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
-
#covered_by?(patterns) ⇒ Boolean
Check if covered by any pattern in a list.
-
#dest_app ⇒ String?
Get destination application from subject.
-
#dlq? ⇒ Boolean
Check if this is a DLQ subject.
- #hash ⇒ Object
-
#initialize(value) ⇒ Subject
constructor
A new instance of Subject.
-
#matches?(pattern) ⇒ Boolean
Check if this subject matches a pattern.
-
#overlaps?(other) ⇒ Boolean
Check if this subject overlaps with another.
-
#source_app ⇒ String?
Get source application from subject.
- #to_s ⇒ Object
Constructor Details
#initialize(value) ⇒ Subject
Returns a new instance of Subject.
23 24 25 26 27 28 29 30 |
# File 'lib/jetstream_bridge/models/subject.rb', line 23 def initialize(value) @value = value.to_s @tokens = @value.split(SEPARATOR) validate! @value.freeze @tokens.freeze freeze end |
Instance Attribute Details
#tokens ⇒ Object (readonly)
Returns the value of attribute tokens.
21 22 23 |
# File 'lib/jetstream_bridge/models/subject.rb', line 21 def tokens @tokens end |
#value ⇒ Object (readonly)
Returns the value of attribute value.
21 22 23 |
# File 'lib/jetstream_bridge/models/subject.rb', line 21 def value @value end |
Class Method Details
.destination(source:, app_name:) ⇒ Object
37 38 39 |
# File 'lib/jetstream_bridge/models/subject.rb', line 37 def self.destination(source:, app_name:) new("#{source}.sync.#{app_name}") end |
.dlq(app_name:) ⇒ Object
41 42 43 |
# File 'lib/jetstream_bridge/models/subject.rb', line 41 def self.dlq(app_name:) new("#{app_name}.sync.dlq") end |
.parse(string) ⇒ Subject
Parse a subject string into a Subject object with metadata
49 50 51 |
# File 'lib/jetstream_bridge/models/subject.rb', line 49 def self.parse(string) new(string) end |
.source(app_name:, dest:) ⇒ Object
Factory methods
33 34 35 |
# File 'lib/jetstream_bridge/models/subject.rb', line 33 def self.source(app_name:, dest:) new("#{app_name}.sync.#{dest}") end |
.subject_matcher ⇒ Object
Lazy-load SubjectMatcher to avoid circular dependency
130 131 132 133 |
# File 'lib/jetstream_bridge/models/subject.rb', line 130 def self.subject_matcher require_relative '../topology/subject_matcher' unless defined?(JetstreamBridge::SubjectMatcher) JetstreamBridge::SubjectMatcher end |
.validate_component!(value, name) ⇒ Object
Validate a component (env, app_name, etc.) for use in subjects
109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/jetstream_bridge/models/subject.rb', line 109 def self.validate_component!(value, name) str = value.to_s if str.match?(INVALID_CHARS) wildcards = "#{SEPARATOR}, #{WILDCARD_SINGLE}, #{WILDCARD_MULTI}" raise ArgumentError, "#{name} cannot contain NATS wildcards (#{wildcards}): #{value.inspect}" end raise ArgumentError, "#{name} cannot be empty" if str.strip.empty? true end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
98 99 100 |
# File 'lib/jetstream_bridge/models/subject.rb', line 98 def ==(other) @value == (other.is_a?(Subject) ? other.value : other.to_s) end |
#covered_by?(patterns) ⇒ Boolean
Check if covered by any pattern in a list
90 91 92 |
# File 'lib/jetstream_bridge/models/subject.rb', line 90 def covered_by?(patterns) SubjectMatcher.covered?(Array(patterns).map(&:to_s), @value) end |
#dest_app ⇒ String?
Get destination application from subject
66 67 68 |
# File 'lib/jetstream_bridge/models/subject.rb', line 66 def dest_app @tokens[2] end |
#dlq? ⇒ Boolean
Check if this is a DLQ subject
DLQ subjects follow the pattern: app.sync.dlq
75 76 77 |
# File 'lib/jetstream_bridge/models/subject.rb', line 75 def dlq? @tokens.length == 3 && @tokens[1] == 'sync' && @tokens[2] == 'dlq' end |
#hash ⇒ Object
104 105 106 |
# File 'lib/jetstream_bridge/models/subject.rb', line 104 def hash @value.hash end |
#matches?(pattern) ⇒ Boolean
Check if this subject matches a pattern
80 81 82 |
# File 'lib/jetstream_bridge/models/subject.rb', line 80 def matches?(pattern) SubjectMatcher.match?(pattern.to_s, @value) end |
#overlaps?(other) ⇒ Boolean
Check if this subject overlaps with another
85 86 87 |
# File 'lib/jetstream_bridge/models/subject.rb', line 85 def overlaps?(other) SubjectMatcher.overlap?(@value, other.to_s) end |
#source_app ⇒ String?
Get source application from subject
For regular subjects: #source_app.sync.dest For DLQ subjects: app_name.sync.dlq
59 60 61 |
# File 'lib/jetstream_bridge/models/subject.rb', line 59 def source_app @tokens[0] end |
#to_s ⇒ Object
94 95 96 |
# File 'lib/jetstream_bridge/models/subject.rb', line 94 def to_s @value end |