lib/fusuma/config/searcher.rb in fusuma-2.0.0.pre vs lib/fusuma/config/searcher.rb in fusuma-2.0.0.pre2

- old
+ new

@@ -4,11 +4,11 @@ module Fusuma class Config # Search config.yml class Searcher def initialize - @cache + @cache = nil end # @param index [Index] # @param location [Hash] # @return [NilClass] @@ -29,13 +29,27 @@ value = search(next_index, location: next_location) end value end + def search_with_context(index, location:, context:) + 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 + + # @param index [Index] + # @param location [Hash] + # @return [NilClass] + # @return [Hash] + # @return [Object] def search_with_cache(index, location:) - cache([index.cache_key, Searcher.skip?, Searcher.fallback?]) do - search(index, location: location) + cache([index.cache_key, Searcher.context, Searcher.skip?, Searcher.fallback?]) do + search_with_context(index, location: location, context: Searcher.context) end end def cache(key) @cache ||= {} @@ -54,15 +68,75 @@ # 2. fallback to other key # 3. skip the key and go to child location def next_location_cadidates(location, key) [ location[key.symbol], - Searcher.fallback? && key.fallback && location[key.fallback], Searcher.skip? && key.skippable && location ].compact end class << self + # @return [Hash] + def conditions(&block) + { + nothing: -> { block.call }, + skip: -> { Config::Searcher.skip { block.call } } + } + end + + # Execute block with specified conditions + # @param conidtion [Symbol] + # @return [Object] + def with_condition(condition, &block) + conditions(&block)[condition].call + end + + # Execute block with all conditions + # @return [Array<Symbol, Object>] + def find_condition(&block) + conditions(&block).find do |c, l| + result = l.call + return [c, result] if result + + nil + end + end + + # Search with context from load_streamed Config + # @param context [Hash] + # @return [Object] + def with_context(context, &block) + @context = context || {} + result = block.call + @context = {} + result + end + + # Return a matching context from config + # @params request_context [Hash] + # @return [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 + + attr_reader :context + def fallback? @fallback end def skip?