Completed
Push — dev ( ffd8f7...ec8098 )
by Fike
51s
created

Primitive   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 48
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 5
c 1
b 0
f 0
dl 0
loc 48
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A mapping_error() 0 3 1
A downgrade_klass() 0 5 1
A supports() 0 3 1
A denormalize() 0 15 2
1
# frozen_string_literal: true
2
3
require_relative '../../exception/mapping_error'
4
5
module AMA
6
  module Entity
7
    class Mapper
8
      class Engine
9
        class Denormalizer
10
          # Standard-interface denormalizer for denormalizing primitives.
11
          class Primitive
12
            MAPPING = {
13
              String => [],
14
              Symbol => [:to_sym],
15
              Numeric => %i[to_f to_i],
16
              TrueClass => [:to_bool],
17
              FalseClass => [:to_bool],
18
              Array => [:to_a],
19
              Hash => %i[to_h to_hash],
20
              NilClass => []
21
            }.freeze
22
23
            # @param [AMA::Entity::Mapper::Type::Concrete] type
24
            def supports(type)
25
              !downgrade_klass(type.type).nil?
26
            end
27
28
            # @param [Object] value
29
            # @param [AMA::Entity::Mapper::Engine::Context] _context
30
            # @param [AMA::Entity::Mapper::Type::Concrete] target_type
31
            def denormalize(value, _context, target_type)
32
              return value if value.is_a?(target_type.type)
33
              methods = MAPPING[downgrade_klass(target_type.type)]
34
              methods.each do |method|
35
                next unless value.respond_to?(method)
36
                begin
37
                  result = value.send(method)
38
                rescue ArgumentError
39
                  next
40
                end
41
                return result if result.is_a?(target_type.type)
42
              end
43
              message = "Can't denormalize #{target_type} out of #{value.class}"
44
              mapping_error(message)
45
            end
46
47
            private
48
49
            def downgrade_klass(klass)
50
              klass.ancestors.find do |ancestor|
51
                MAPPING.key?(ancestor)
52
              end
53
            end
54
55
            def mapping_error(message)
56
              raise ::AMA::Entity::Mapper::Exception::MappingError, message
57
            end
58
          end
59
        end
60
      end
61
    end
62
  end
63
end
64