Module: Textus::Domain::Policy::Matcher

Defined in:
lib/textus/domain/policy/matcher.rb

Class Method Summary collapse

Class Method Details

.consume(glob_segs, key_segs) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/textus/domain/policy/matcher.rb', line 30

def self.consume(glob_segs, key_segs)
  return key_segs.empty? if glob_segs.empty?

  head = glob_segs.first
  rest = glob_segs[1..]

  if head == "**"
    return true if rest.empty?

    (0..key_segs.length).any? { |i| consume(rest, key_segs[i..]) }
  elsif key_segs.empty?
    false
  elsif head == "*" || head == key_segs.first
    consume(rest, key_segs[1..])
  else
    false
  end
end

.matches?(glob, key) ⇒ Boolean

Returns:

  • (Boolean)


7
8
9
10
11
# File 'lib/textus/domain/policy/matcher.rb', line 7

def matches?(glob, key)
  glob_segs = glob.split(".")
  key_segs  = key.split(".")
  consume(glob_segs, key_segs)
end

.pick_most_specific(globs, key:) ⇒ Object



23
24
25
26
27
28
# File 'lib/textus/domain/policy/matcher.rb', line 23

def pick_most_specific(globs, key:)
  matching = globs.select { |g| matches?(g, key) }
  return nil if matching.empty?

  matching.max_by { |g| [specificity(g), -g.length, g] }
end

.specificity(glob) ⇒ Object



13
14
15
16
17
18
19
20
21
# File 'lib/textus/domain/policy/matcher.rb', line 13

def specificity(glob)
  glob.split(".").reduce(0) do |s, seg|
    s + case seg
        when "**" then 0
        when "*"  then 1
        else 10
        end
  end
end