class Flows::Contract::Hash
Contract
for Ruby `Hash` with specified contracts for keys and values.
If key contract has transformation - Hash
keys will be transformed.
If value contract has transformation - Hash
values will be transformed.
@example
sym_int_hash = Flows::Contract::Hash.new(Symbol, Integer) sym_int_hash === { a: 1, b: 2 } # => true sym_int_hash === { a: 1, b: 'BBB' } # => true
Constants
- CHECK_LIMIT
Stop search for a new type mismatch in keys or values if
CHECK_LIMIT
errors already found.Applied separately for keys and values.
- HASH_TYPE
Public Class Methods
new(key_contract, value_contract)
click to toggle source
@param key_contract [Contract, Object] contract for keys, non-contract values will be wrapped with {CaseEq} @param value_contract [Contract, Object] contract for values, non-contract values will be wrapped with {CaseEq}
# File lib/flows/contract/hash.rb, line 28 def initialize(key_contract, value_contract) @key_contract = to_contract(key_contract) @value_contract = to_contract(value_contract) end
Public Instance Methods
check!(other)
click to toggle source
# File lib/flows/contract/hash.rb, line 33 def check!(other) HASH_TYPE.check!(other) unless other.keys.all?(&@key_contract) && other.values.all?(&@value_contract) value_error = report_error(other) raise Error.new(other, value_error) end true end
transform!(other)
click to toggle source
# File lib/flows/contract/hash.rb, line 44 def transform!(other) check!(other) other .transform_keys { |key| @key_contract.transform!(key) } .transform_values { |value| @value_contract.transform!(value) } end
Private Instance Methods
invalid_key_errors(other)
click to toggle source
# File lib/flows/contract/hash.rb, line 58 def invalid_key_errors(other) other.keys.reject(&@key_contract)[0..CHECK_LIMIT].map do |key| key_error = @key_contract.check(key).error merge_nested_errors("hash key `#{key.inspect}` is invalid:", key_error) end end
invalid_value_errors(other)
click to toggle source
# File lib/flows/contract/hash.rb, line 66 def invalid_value_errors(other) other.values.reject(&@value_contract)[0..CHECK_LIMIT].map do |value| value_error = @value_contract.check(value).error merge_nested_errors("hash value `#{value.inspect}` is invalid:", value_error) end end
report_error(other)
click to toggle source
# File lib/flows/contract/hash.rb, line 54 def report_error(other) (invalid_key_errors(other) + invalid_value_errors(other)).join("\n") end