Module: JetstreamBridge::SubjectMatcher
- Defined in:
- lib/jetstream_bridge/topology/subject_matcher.rb
Overview
Subject matching helpers.
Class Method Summary collapse
- .covered?(patterns, subject) ⇒ Boolean
-
.match?(pattern, subject) ⇒ Boolean
Proper NATS semantics: - ‘*’ matches exactly one token - ‘>’ matches the rest (zero or more tokens).
-
.overlap?(sub_a, sub_b) ⇒ Boolean
Do two wildcard patterns admit at least one same subject?.
- .overlap_parts?(a_parts, b_parts) ⇒ Boolean
- .tail?(a_token, b_token) ⇒ Boolean
- .tail_overlap?(a_tail, b_tail) ⇒ Boolean
- .token_match?(a_token, b_token) ⇒ Boolean
Class Method Details
.covered?(patterns, subject) ⇒ Boolean
8 9 10 |
# File 'lib/jetstream_bridge/topology/subject_matcher.rb', line 8 def covered?(patterns, subject) Array(patterns).any? { |pat| match?(pat.to_s, subject.to_s) } end |
.match?(pattern, subject) ⇒ Boolean
Proper NATS semantics:
-
‘*’ matches exactly one token
-
‘>’ matches the rest (zero or more tokens)
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/jetstream_bridge/topology/subject_matcher.rb', line 15 def match?(pattern, subject) p = pattern.split('.') s = subject.split('.') i = 0 while i < p.length && i < s.length token = p[i] case token when '>' return true # tail wildcard absorbs the rest when '*' # matches this token; continue else return false unless token == s[i] end i += 1 end # Exact match return true if i == p.length && i == s.length # If pattern has remaining '>' it can absorb remainder p[i] == '>' || p[i..]&.include?('>') end |
.overlap?(sub_a, sub_b) ⇒ Boolean
Do two wildcard patterns admit at least one same subject?
41 42 43 |
# File 'lib/jetstream_bridge/topology/subject_matcher.rb', line 41 def overlap?(sub_a, sub_b) overlap_parts?(sub_a.split('.'), sub_b.split('.')) end |
.overlap_parts?(a_parts, b_parts) ⇒ Boolean
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/jetstream_bridge/topology/subject_matcher.rb', line 45 def overlap_parts?(a_parts, b_parts) ai = 0 bi = 0 while ai < a_parts.length && bi < b_parts.length at = a_parts[ai] bt = b_parts[bi] return true if tail?(at, bt) return false unless token_match?(at, bt) ai += 1 bi += 1 end tail_overlap?(a_parts[ai..], b_parts[bi..]) end |
.tail?(a_token, b_token) ⇒ Boolean
61 62 63 |
# File 'lib/jetstream_bridge/topology/subject_matcher.rb', line 61 def tail?(a_token, b_token) a_token == '>' || b_token == '>' end |
.tail_overlap?(a_tail, b_tail) ⇒ Boolean
69 70 71 72 73 74 75 |
# File 'lib/jetstream_bridge/topology/subject_matcher.rb', line 69 def tail_overlap?(a_tail, b_tail) a_tail ||= [] b_tail ||= [] return true if a_tail.include?('>') || b_tail.include?('>') a_tail.empty? && b_tail.empty? end |
.token_match?(a_token, b_token) ⇒ Boolean
65 66 67 |
# File 'lib/jetstream_bridge/topology/subject_matcher.rb', line 65 def token_match?(a_token, b_token) a_token == b_token || a_token == '*' || b_token == '*' end |