Completed
Push — dev ( ff1c91...ab1075 )
by Fike
01:06
created

HashType.initialize()   A

Complexity

Conditions 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 1
1
# frozen_string_literal: true
2
3
require_relative '../../type'
4
require_relative '../../path/segment'
5
require_relative '../../mixin/errors'
6
require_relative '../../mixin/reflection'
7
require_relative 'hash_tuple_type'
8
require_relative '../aux/hash_tuple'
9
10
module AMA
11
  module Entity
12
    class Mapper
13
      class Type
14
        module BuiltIn
15
          # Predefined type for Hash class
16
          class HashType < Type
17
            include Mixin::Errors
18
            extend Mixin::Errors
19
20
            def initialize
21
              super(::Hash)
22
              define_attribute
23
              define_enumerator
24
              define_injector
25
              define_normalizer
26
              define_denormalizer
27
            end
28
29
            private
30
31
            def define_attribute
32
              type = HashTupleType.new
33
              type = type.resolve(
34
                type.parameter!(:K) => parameter!(:K),
35
                type.parameter!(:V) => parameter!(:V)
36
              )
37
              attribute!(:_tuple, type, virtual: true)
38
            end
39
40
            def define_enumerator
41
              enumerator_block do |entity, type, *|
42
                ::Enumerator.new do |yielder|
43
                  entity.each do |key, value|
44
                    tuple = Aux::HashTuple.new(key: key, value: value)
45
                    attribute = type.attributes[:_tuple]
46
                    yielder << [attribute, tuple, Path::Segment.index(key)]
47
                  end
48
                end
49
              end
50
            end
51
52
            def define_injector
53
              injector_block do |entity, _, _, tuple, *|
54
                entity[tuple.key] = tuple.value
55
              end
56
            end
57
58
            def define_denormalizer
59
              denormalizer_block do |input, type, context = nil, *|
60
                input = input.to_h if input.respond_to?(:to_h)
61
                break input if input.is_a?(Hash)
62
                message = "Expected to receive hash, #{input.class} received"
63
                type.mapping_error(message, context: context)
64
              end
65
            end
66
67
            def define_normalizer
68
              normalizer_block do |entity, *|
69
                entity.clone
70
              end
71
            end
72
73
            INSTANCE = new
74
          end
75
        end
76
      end
77
    end
78
  end
79
end
80