class Flows::Contract::HashOf
Contract
for Ruby `Hash` with specified structure.
Hash
can have extra keys. Extra keys will be removed after transform. Underlying contracts' transforms will be applied to correspond values.
@example
point_type = Flows::Contract::HashOf.new(x: Numeric, y: Numeric) point_type === { x: 1, y: 2.0 } # => true point_type === { x: 1, y: 2.0, name: 'Petr' } # => true point_type.cast(x: 1, y: 2.0, name: 'Petr').unwrap # => { x: 1, y: 2.0 } point_type.check({ x: 1, name: 'Petr' }) # => Flows::Result::Error.new('missing key `:y`') point_type.check({ x: 1, y: 'Vasya' }) # => Flows::Result::Error.new('key `:y` has an invalid value: must match `Numeric`')
Constants
- HASH_CONTRACT
Public Class Methods
new(shape = {})
click to toggle source
# File lib/flows/contract/hash_of.rb, line 28 def initialize(shape = {}) @shape = shape.transform_values(&method(:to_contract)) end
Public Instance Methods
check!(other)
click to toggle source
# File lib/flows/contract/hash_of.rb, line 32 def check!(other) HASH_CONTRACT.check!(other) errors = check_shape(other) raise Error.new(other, errors.join("\n")) if errors.any? true end
transform!(other)
click to toggle source
# File lib/flows/contract/hash_of.rb, line 42 def transform!(other) check!(other) other .slice(*@shape.keys) .map { |key, value| [key, @shape[key].transform!(value)] } .to_h end
Private Instance Methods
check_shape(other)
click to toggle source
:reek: DuplicateMethodCall
# File lib/flows/contract/hash_of.rb, line 54 def check_shape(other) @shape.each_with_object([]) do |(key, type), errors| unless other.key?(key) errors << "missing hash key `#{key.inspect}`" next end result = type.check(other[key]) if result.err? errors << merge_nested_errors("hash key `#{key.inspect}` has an invalid assigned value:", result.error) end end end