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

Enumerator.enumerate()   A

Complexity

Conditions 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 11
rs 9.4285
cc 1
1
# frozen_string_literal: true
2
3
require_relative '../../mixin/reflection'
4
require_relative '../../path/segment'
5
6
module AMA
7
  module Entity
8
    class Mapper
9
      module Handler
10
        module Entity
11
          # Default attribute enumerator
12
          class Enumerator
13
            include Mixin::Reflection
14
15
            INSTANCE = new
16
17
            # @param [Object] entity
18
            # @param [AMA::Entity::Mapper::Type] type
19
            # @param [AMA::Entity::Mapper::Context] _context
20
            def enumerate(entity, type, _context)
21
              ::Enumerator.new do |yielder|
22
                type.attributes.values.each do |attribute|
23
                  next if attribute.virtual
24
                  next unless object_variable_exists(entity, attribute.name)
25
                  value = object_variable(entity, attribute.name)
26
                  segment = Path::Segment.attribute(attribute.name)
27
                  yielder << [attribute, value, segment]
28
                end
29
              end
30
            end
31
32
            class << self
33
              include Mixin::Reflection
34
35
              # @param [Enumerator] implementation
36
              # @return [Enumerator]
37 View Code Duplication
              def wrap(implementation)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
38
                handler = handler_factory(implementation, INSTANCE)
39
                description = "Safety wrapper for #{implementation}"
40
                wrapper = method_object(:enumerate, to_s: description, &handler)
41
                wrapper.singleton_class.instance_eval do
42
                  include Mixin::Errors
43
                end
44
                wrapper
45
              end
46
47
              private
48
49
              # @param [Enumerator] implementation
50
              # @param [Enumerator] fallback
51
              # @return [Enumerator]
52
              def handler_factory(implementation, fallback)
53
                lambda do |entity, type, ctx|
54
                  begin
55
                    implementation.enumerate(entity, type, ctx) do |e, t, c|
56
                      fallback.enumerate(e, t, c)
57
                    end
58
                  rescue StandardError => e
59
                    raise_if_internal(e)
60
                    message = 'Unexpected error from enumerator ' \
61
                      "#{implementation}"
62
                    signature = '(entity, type, context)'
63
                    options = { parent: e, context: ctx, signature: signature }
64
                    compliance_error(message, **options)
65
                  end
66
                end
67
              end
68
            end
69
          end
70
        end
71
      end
72
    end
73
  end
74
end
75