douglaslise/wonder_navigation

View on GitHub
lib/wonder_navigation/deferrable_option.rb

Summary

Maintainability
A
0 mins
Test Coverage
module WonderNavigation
  class DeferrableOption
    attr_accessor :fixed_value, :block, :name, :fixed_value_assigned

    def initialize(options = {})
      @fixed_value_assigned = options.has_key?(:fixed) && !options[:fixed].nil?
      @fixed_value = options[:fixed]
      @block       = options[:block]
      @name        = options[:name]
    end

    def present?
      fixed_value_assigned || !!block
    end

    def resolvable?(object)
      fixed_value_assigned || !!block && (!!object || block.arity.zero?)
    end

    def try_resolve(object)
      resolve(object) if resolvable?(object)
    end

    def resolve(object)
      check_resolvable(object)
      fixed_value_assigned ? fixed_value : block.call(object)
    end

    private

    def check_resolvable(object)
      unless resolvable?(object)
        if present?
          raise EObjectNotSupplied.new "A block was defined to require an object but none (or nil) was supplied on deferrable option #{name}"
        else
          raise EDeferrableOptionEmpty.new "Neither a fixed value or a block was passed to deferrable option #{name}"
        end
      end
    end
  end
  class EObjectNotSupplied < StandardError; end
  class EDeferrableOptionEmpty < StandardError; end
end