Completed
Push — master ( 308a2c...1aebdd )
by Fike
01:00
created

Factory   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 69
Duplicated Lines 13.04 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 6
c 1
b 0
f 0
dl 9
loc 69
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A handler_factory() 0 15 1
A create_internal() 0 10 1
A wrap() 9 9 1
A create() 0 9 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
# frozen_string_literal: true
2
3
require_relative '../../mixin/errors'
4
require_relative '../../mixin/reflection'
5
require_relative '../../path/segment'
6
7
module AMA
8
  module Entity
9
    class Mapper
10
      module Handler
11
        module Entity
12
          # Default entity factory
13
          class Factory
14
            include Mixin::Errors
15
16
            INSTANCE = new
17
18
            # @param [AMA::Entity::Mapper::Type] type
19
            # @param [Object] _data
20
            # @param [AMA::Entity::Mapper::Context] context
21
            def create(type, _data, context)
22
              create_internal(type)
23
            rescue StandardError => e
24
              message = "Failed to instantiate #{type} directly from class"
25
              if e.is_a?(ArgumentError)
26
                message += '. Does it have parameterless #initialize() method?'
27
              end
28
              mapping_error(message, parent: e, context: context)
29
            end
30
31
            private
32
33
            # @param [AMA::Entity::Mapper::Type] type
34
            def create_internal(type)
35
              entity = type.type.new
36
              type.attributes.values.each do |attribute|
37
                next if attribute.default.nil? || attribute.virtual
38
                segment = Path::Segment.attribute(attribute.name)
39
                value = attribute.default
40
                type.injector.inject(entity, type, attribute, value, segment)
41
              end
42
              entity
43
            end
44
45
            class << self
46
              include Mixin::Reflection
47
48
              # @param [Factory] implementation
49
              # @return [Factory]
50 View Code Duplication
              def wrap(implementation)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
51
                handler = handler_factory(implementation, INSTANCE)
52
                description = "Safety wrapper for #{implementation}"
53
                wrapper = method_object(:create, to_s: description, &handler)
54
                wrapper.singleton_class.instance_eval do
55
                  include Mixin::Errors
56
                end
57
                wrapper
58
              end
59
60
              private
61
62
              # @param [Factory] implementation
63
              # @param [Factory] fallback
64
              # @return [Factory]
65
              def handler_factory(implementation, fallback)
66
                lambda do |type, data, ctx|
67
                  begin
68
                    implementation.create(type, data, ctx) do |t, d, c|
69
                      fallback.create(t, d, c)
70
                    end
71
                  rescue StandardError => e
72
                    raise_if_internal(e)
73
                    message = "Unexpected error from factory #{implementation}"
74
                    signature = '(type, data, context)'
75
                    options = { parent: e, context: ctx, signature: signature }
76
                    compliance_error(message, options)
77
                  end
78
                end
79
              end
80
            end
81
          end
82
        end
83
      end
84
    end
85
  end
86
end
87