class HashPolice::Police

Attributes

context_key[R]
rule[R]

Public Class Methods

new(rule, context_key = "") click to toggle source
# File lib/hash_police/police.rb, line 7
def initialize rule, context_key = ""
  @rule = rule
  @passed = false
  @context_key = context_key
end

Public Instance Methods

check(target) click to toggle source
# File lib/hash_police/police.rb, line 13
def check target
  result = CheckResult.new(context_key)
  if rule.kind_of?(Proc) && ! rule.call(target)
    result.invalid_by_proc
    return result
  end

  unless type_matched?(rule, target)
    result.differ_type(:expect => rule.class, :got => target.class)
    return result
  end

  unless scalar?(rule)
    context_prefix = context_key == "" ? "" : "#{context_key}."
    if rule.kind_of?(Array)
      target.each_with_index do |t, index|
        police = self.class.new(rule.first, "#{context_prefix}#{index}")
        result.concat(police.check(t))
      end
    end

    if rule.kind_of?(Hash)
      rule = stringify_keys(self.rule)
      target = stringify_keys(target)

      rule.each do |rule_key, rule_val|
        if target.has_key?(rule_key)
          police = self.class.new(rule_val, "#{context_prefix}#{rule_key}")
          result.concat(police.check(target[rule_key]))
        else
          result.missing("#{context_prefix}#{rule_key}")
        end
      end
    end
  end

  result
end

Private Instance Methods

bool?(val) click to toggle source
# File lib/hash_police/police.rb, line 61
def bool? val
  !! val == val
end
scalar?(val) click to toggle source
# File lib/hash_police/police.rb, line 65
def scalar? val
  ! val.kind_of?(Array) && ! val.kind_of?(Hash)
end
stringify_keys(hash) click to toggle source
# File lib/hash_police/police.rb, line 69
def stringify_keys hash
  hash.reduce({}) do |memo,(k,v)|
    memo[k.to_s] = v
    memo
  end
end
type_matched?(rule, target) click to toggle source
# File lib/hash_police/police.rb, line 53
def type_matched? rule, target
  return true if bool?(rule) && bool?(target)
  if rule.kind_of?(Proc)
    return !!rule.call(target)
  end
  rule.class == target.class
end