class Fusuma::Config::Searcher

Search config.yml

def cache(key)

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

def conditions(&block)

Returns:
  • (Hash) -
def conditions(&block)
  {
    nothing: -> { block.call },
    skip: -> { Config::Searcher.skip { block.call } }
  }
end

def fallback(&block)

switch context for fallback
def fallback(&block)
  @fallback = true
  result = block.call
  @fallback = false
  result
end

def fallback?

def fallback?
  @fallback
end

def find_condition(&block)

Returns:
  • (Array) -
def find_condition(&block)
  conditions(&block).find do |c, l|
    result = l.call
    return [c, result] if result
    nil
  end
end

def find_context(request_context, &block)

Returns:
  • (Hash) -
def find_context(request_context, &block)
  # Search in blocks in the following order.
  # 1. complete match config[:context] == request_context
  # 2. partial match config[:context] =~ request_context
  # 3. no context
  Config.instance.keymap.each do |config|
    next unless config[:context] == request_context
    return config[:context] if with_context(config[:context]) { block.call }
  end
  if request_context.keys.size > 1
    Config.instance.keymap.each do |config|
      next if config[:context].nil?
      next unless config[:context].all? { |k, v| request_context[k] == v }
      return config[:context] if with_context(config[:context]) { block.call }
    end
  end
  return {} if with_context({}) { block.call }
end

def initialize

def initialize
  @cache = nil
end

def next_location_cadidates(location, key)

2. skip the key and go to child location
1. look up location with key
next locations' candidates sorted by priority
def next_location_cadidates(location, key)
  [
    location[key.symbol],
    Searcher.skip? && key.skippable && location
  ].compact
end

def search(index, location:)

Returns:
  • (Object) -
  • (Hash) -
  • (NilClass) -

Parameters:
  • location (Hash) --
  • index (Index) --
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[1..-1])
  value = nil
  next_location_cadidates(location, key).find do |next_location|
    value = search(next_index, location: next_location)
  end
  value
end

def search_with_cache(index, location:)

Returns:
  • (Object) -
  • (Hash) -
  • (NilClass) -

Parameters:
  • location (Hash) --
  • index (Index) --
def search_with_cache(index, location:)
  cache([index.cache_key, Searcher.context, Searcher.skip?, Searcher.fallback?]) do
    search_with_context(index, location: location, context: Searcher.context)
  end
end

def search_with_context(index, location:, context:)

def search_with_context(index, location:, context:)
  return nil if location.nil?
  return search(index, location: location[0]) if context == {}
  new_location = location.find do |conf|
    search(index, location: conf) if conf[:context] == context
  end
  search(index, location: new_location)
end

def skip(&block)

def skip(&block)
  @skip = true
  result = block.call
  @skip = false
  result
end

def skip?

def skip?
  @skip
end

def with_condition(condition, &block)

Returns:
  • (Object) -

Parameters:
  • conidtion (Symbol) --
def with_condition(condition, &block)
  conditions(&block)[condition].call
end

def with_context(context, &block)

Returns:
  • (Object) -

Parameters:
  • context (Hash) --
def with_context(context, &block)
  @context = context || {}
  result = block.call
  @context = {}
  result
end