PrimitiveType
last analyzed

Complexity

Total Complexity 0

Size/Duplication

Total Lines 47
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 0
c 2
b 0
f 0
dl 0
loc 47

3 Methods

Rating   Name   Duplication   Size   Complexity  
A Denormalizer.initialize() 0 3 1
A Denormalizer.find_candidate_methods() 0 12 3
A Denormalizer.denormalize() 0 17 2
1
# frozen_string_literal: true
2
3
require_relative '../../../type'
4
require_relative '../../../mixin/errors'
5
6
module AMA
7
  module Entity
8
    class Mapper
9
      class Type
10
        module BuiltIn
11
          class PrimitiveType < Type
12
            # Standard denormalizer for primitive type
13
            class Denormalizer
14
              include Mixin::Errors
15
16
              # @param [Hash{Class, Array<Symbol>}] method_map
17
              def initialize(method_map)
18
                @method_map = method_map
19
              end
20
21
              # @param [Object] source
22
              # @param [AMA::Entity::Mapper::Type] type
23
              # @param [AMA::Entity::Mapper::Context] context
24
              def denormalize(source, type, context)
25
                return source if type.valid?(source, context)
26
                find_candidate_methods(source.class).each do |candidate|
27
                  begin
28
                    next unless source.respond_to?(candidate)
29
                    value = source.send(candidate)
30
                    return value if type.valid?(value, context)
31
                  rescue StandardError => e
32
                    message = "Method #{candidate} failed with error when " \
33
                      "denormalizing #{type.type} out of #{source.class}: " \
34
                      "#{e.message}"
35
                    context.logger.warn(message)
36
                  end
37
                end
38
                message = "Can't create #{type} instance from #{source.class}"
39
                mapping_error(message, context: context)
40
              end
41
42
              private
43
44
              def find_candidate_methods(klass)
45
                chain = []
46
                cursor = klass
47
                until cursor.nil?
48
                  chain.push(cursor)
49
                  cursor = cursor.superclass
50
                end
51
                winner = chain.find do |entry|
52
                  @method_map.key?(entry)
53
                end
54
                winner.nil? ? [] : @method_map[winner]
55
              end
56
            end
57
          end
58
        end
59
      end
60
    end
61
  end
62
end
63