Class: Fusuma::Config::Searcher

Inherits:
Object
  • Object
show all
Defined in:
lib/fusuma/config/searcher.rb

Overview

Search config.yml

Constant Summary collapse

CONTEXT_SEARCH_ORDER =
[:no_context, :complete_match_context, :partial_match_context]

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSearcher

: () -> void



9
10
11
# File 'lib/fusuma/config/searcher.rb', line 9

def initialize
  @cache = {}
end

Class Attribute Details

.contextObject (readonly)

Returns the value of attribute context.



93
94
95
# File 'lib/fusuma/config/searcher.rb', line 93

def context
  @context
end

Class Method Details

.find_context(request_context, fallbacks = CONTEXT_SEARCH_ORDER, &block) ⇒ Hash

Return a matching context from config : (Hash[untyped, untyped], ?Array) { () -> untyped } -> Hash[untyped, untyped]?

Returns:



112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/fusuma/config/searcher.rb', line 112

def find_context(request_context, fallbacks = CONTEXT_SEARCH_ORDER, &block)
  # Search in blocks in the following order.
  # 1. no_context: primary context (no context specified)
  # 2. complete_match_context: config[:context] matches request_context
  #    - Supports OR condition (array values)
  #    - Supports AND condition (multiple keys)
  # 3. partial_match_context: config[:context] partially matches request_context
  fallbacks.find do |method|
    result = send(method, request_context, &block)
    return result if result
  end
end

.with_context(context = {}, &block) ⇒ Object

Search with context from load_streamed Config : (?Hash[untyped, untyped]) { () -> untyped } -> untyped

Parameters:

  • context (Hash) (defaults to: {})

Returns:

  • (Object)


99
100
101
102
103
104
105
# File 'lib/fusuma/config/searcher.rb', line 99

def with_context(context = {}, &block)
  before = @context
  @context = context
  block.call
ensure # NOTE: ensure is called even if return in block
  @context = before
end

Instance Method Details

#cache(key) ⇒ Object

: (Array | String) { () -> untyped } -> untyped



70
71
72
73
74
75
76
77
# File 'lib/fusuma/config/searcher.rb', line 70

def cache(key)
  key = key.join(",") if key.is_a? Array
  if @cache.key?(key)
    @cache[key]
  else
    @cache[key] = block_given? ? yield : nil
  end
end

#search(index, location:) ⇒ NilClass, ...

: (Fusuma::Config::Index, location: untyped) -> untyped

Parameters:

Returns:

  • (NilClass)
  • (Hash)
  • (Object)


19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/fusuma/config/searcher.rb', line 19

def search(index, location:)
  key = index.keys.first
  return location if key.nil?
  return nil if location.nil?
  return nil unless location.is_a?(Hash)

  next_index = Index.new(index.keys.drop(1))

  next_location_cadidates(location, key).each do |next_location|
    result = search(next_index, location: next_location)
    return result if result
  end
  nil
end

#search_with_cache(index, location:) ⇒ NilClass, ...

: (Fusuma::Config::Index, location: Array)

Parameters:

Returns:

  • (NilClass)
  • (Hash)
  • (Object)


63
64
65
66
67
# File 'lib/fusuma/config/searcher.rb', line 63

def search_with_cache(index, location:)
  cache([index.cache_key, Searcher.context]) do
    search_with_context(index, location: location, context: Searcher.context)
  end
end

#search_with_context(index, location:, context:) ⇒ Object

: (Fusuma::Config::Index, location: Array, context: Hash[untyped, untyped] | nil) -> untyped



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/fusuma/config/searcher.rb', line 35

def search_with_context(index, location:, context:)
  return nil if location.nil?

  # When context is nil or empty, search in no-context config blocks
  if context.nil? || context == {}
    no_context_conf = location.find { |conf| conf[:context].nil? }
    return no_context_conf ? search(index, location: no_context_conf) : nil
  end

  # When context is specified, search only in context-having config blocks
  value = nil
  location.each do |conf|
    next if conf[:context].nil? # skip no-context blocks

    if ContextMatcher.match?(conf[:context], context)
      value = search(index, location: conf)
      break if value
    end
  end
  value
end