Class: Flows::Contract::HashOf

Inherits:
Flows::Contract show all
Defined in:
lib/flows/contract/hash_of.rb

Overview

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.

Examples:

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`')

Since:

  • 0.4.0

Constant Summary collapse

HASH_CONTRACT =

Since:

  • 0.4.0

CaseEq.new(::Hash)

Instance Method Summary collapse

Methods inherited from Flows::Contract

#===, #check, make, #to_proc, #transform

Constructor Details

#initialize(shape = {}) ⇒ HashOf

Returns a new instance of HashOf.

Since:

  • 0.4.0



28
29
30
# File 'lib/flows/contract/hash_of.rb', line 28

def initialize(shape = {})
  @shape = shape.transform_values(&method(:to_contract))
end

Instance Method Details

#check!(other) ⇒ Object

Raises:

Since:

  • 0.4.0



32
33
34
35
36
37
38
39
40
# 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) ⇒ Object

Since:

  • 0.4.0



42
43
44
45
46
47
48
49
# 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