Class: Textus::Action::RuleExplain

Inherits:
Base
  • Object
show all
Defined in:
lib/textus/action/rule_explain.rb

Constant Summary collapse

REGISTRY =
Textus::Manifest::Schema::FIELD_REGISTRY
LEAN_FIELDS =
REGISTRY.select { |_, m| m[:in_rule_explain].include?(:lean) }.keys.freeze
DETAIL_FIELDS =
REGISTRY.select { |_, m| m[:in_rule_explain].include?(:detail) }.keys.freeze
EFFECTIVE_FIELDS =
DETAIL_FIELDS.select { |f| REGISTRY[f][:policy_class] }.freeze

Class Method Summary collapse

Methods inherited from Base

inherited, proposal_from

Methods included from Contract::DSL

#arg, #cli, #cli_stdin, #contract, #contract?, #summary, #surfaces, #verb, #view

Class Method Details

.call(container:, call:, key:, detail: nil) ⇒ Object

rubocop:disable Lint/UnusedMethodArgument



16
17
18
19
# File 'lib/textus/action/rule_explain.rb', line 16

def self.call(container:, call:, key:, detail: nil) # rubocop:disable Lint/UnusedMethodArgument
  manifest = container.manifest
  Success(detail ? explain(manifest, key) : effective(manifest, key))
end

.effective(manifest, key) ⇒ Object



26
27
28
29
30
31
32
# File 'lib/textus/action/rule_explain.rb', line 26

def self.effective(manifest, key)
  set = manifest.rules.for(key)
  LEAN_FIELDS.each_with_object({}) do |field, out|
    value = set.public_send(field)
    out[field.to_s] = lean_value(field, value) unless value.nil?
  end
end

.effective_value(field, value) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/textus/action/rule_explain.rb', line 62

def self.effective_value(field, value)
  return nil if value.nil?

  case field
  when :retention
    retention_hash(value, string_keys: false)
  when :react
    value.to_h
  else
    value
  end
end

.explain(manifest, key) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/textus/action/rule_explain.rb', line 45

def self.explain(manifest, key)
  matching = manifest.rules.explain(key)
  winners = manifest.rules.for(key)
  {
    key: key,
    matched_blocks: matching.map do |block|
      { match: block.match }.merge(DETAIL_FIELDS.to_h { |f| [f, !block.public_send(f).nil?] })
    end,
    effective: EFFECTIVE_FIELDS.to_h { |f| [f, effective_value(f, winners.public_send(f))] },
    guards: Textus::Gate::Auth::FLOOR.keys.to_h do |action|
      floor = Textus::Gate::Auth::FLOOR.fetch(action, [])
      rule = Array(manifest.rules.for(key).guard&.dig(action.to_s))
      [action, { floor: floor, rule: rule }]
    end,
  }
end

.lean_value(field, value) ⇒ Object



34
35
36
37
38
39
40
41
42
43
# File 'lib/textus/action/rule_explain.rb', line 34

def self.lean_value(field, value)
  case field
  when :retention
    retention_hash(value, string_keys: true)
  when :react
    value.to_h
  else
    value
  end
end

.retention_hash(retention, string_keys:) ⇒ Object



75
76
77
78
# File 'lib/textus/action/rule_explain.rb', line 75

def self.retention_hash(retention, string_keys:)
  h = { ttl_seconds: retention.ttl_seconds, action: retention.action }
  string_keys ? h.transform_keys(&:to_s) : h
end