Sha256: ccdeddf7c49042916d5970a9ab1a618d6ab40b0cb4c5b1d98b7cd7704ef2591f

Contents?: true

Size: 1.62 KB

Versions: 50

Compression:

Stored size: 1.62 KB

Contents

# frozen_string_literal: true

module Ree::Contracts
  module ArgContracts
    class HashOf
      extend Ree::Contracts::ArgContracts::Squarable
      include Ree::Contracts::Truncatable

      attr_reader :key_validator, :value_validator
      
      def initialize(*contracts)
        if contracts.size != 2
          raise BadContractError, 'HashOf should accept exactly two contracts'
        end

        @key_validator   = Validators.fetch_for(contracts[0])
        @value_validator = Validators.fetch_for(contracts[1])
      end

      def valid?(value)
        value.is_a?(Hash) &&
          value.each_key.all?(&key_validator.method(:call)) &&
          value.each_value.all?(&value_validator.method(:call))
      end

      def to_s
        "HashOf[#{key_validator.to_s}, #{value_validator.to_s}]"
      end

      def message(value, name, lvl = 1)
        unless value.is_a?(Hash)
          return "expected Hash, got #{value.class} => #{truncate(value.inspect)}"
        end

        errors = []
        sps = "  " * lvl

        value.each do |key, val|
          if errors.size > 4
            errors << "\n\t#{sps} - ..."
            break
          end

          unless key_validator.call(key)
            msg = key_validator.message(key, "#{name}[#{key.inspect}]", lvl + 1)
            errors << "\n\t#{sps} - invalid key #{key.inspect}, #{msg}"
          end

          unless value_validator.call(val)
            msg = key_validator.message(val, "#{name}[#{key.inspect}]", lvl + 1)
            errors << "\n\t#{sps} - invalid value for #{key.inspect} key, #{msg}"
          end
        end

        errors.join
      end
    end
  end
end

Version data entries

50 entries across 50 versions & 1 rubygems

Version Path
ree-1.1.1 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.1.0 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.47 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.46 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.45 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.44 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.43 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.42 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.41 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.40 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.39 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.38 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.37 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.36 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.35 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.34 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.33 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.32 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.31 lib/ree/contracts/arg_contracts/hash_of.rb
ree-1.0.30 lib/ree/contracts/arg_contracts/hash_of.rb