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

SetType.initialize()   A

Complexity

Conditions 1

Size

Total Lines 11

Duplication

Lines 11
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 11
loc 11
rs 9.4285
cc 1
1
# frozen_string_literal: true
2
3
require 'set'
4
5
require_relative '../concrete'
6
require_relative '../../path/segment'
7
require_relative '../../mixin/errors'
8
require_relative 'pair_type'
9
require_relative '../aux/pair'
10
11
module AMA
12
  module Entity
13 View Code Duplication
    class Mapper
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
14
      class Type
15
        module Hardwired
16
          # Predefined type for Set class
17
          class SetType < Concrete
18
            def initialize
19
              super(::Set)
20
              attribute!(:_value, parameter!(:T), virtual: true)
21
22
              define_factory
23
              define_normalizer
24
              define_denormalizer
25
              define_enumerator
26
              define_acceptor
27
              define_extractor
28
            end
29
30
            private
31
32
            def define_factory
33
              self.factory = Object.new.tap do |factory|
34
                factory.define_singleton_method(:create) do |*|
35
                  Set.new([])
36
                end
37
              end
38
            end
39
40
            def define_normalizer
41
              self.normalizer = lambda do |input, *|
42
                input.map(&:itself)
43
              end
44
            end
45
46
            def define_denormalizer
47
              self.denormalizer = lambda do |entity, *|
48
                Set.new(entity)
49
              end
50
            end
51
52
            def define_enumerator
53
              self.enumerator = lambda do |entity, type, *|
54
                ::Enumerator.new do |yielder|
55
                  attribute = type.attributes[:_value]
56
                  entity.each_with_index do |value, index|
57
                    yielder << [attribute, value, Path::Segment.index(index)]
58
                  end
59
                end
60
              end
61
            end
62
63
            def define_acceptor
64
              self.acceptor = lambda do |entity, *|
65
                acceptor = Object.new
66
                acceptor.define_singleton_method(:accept) do |_, value, *|
67
                  entity.add(value)
68
                end
69
                acceptor
70
              end
71
            end
72
73
            def define_extractor
74
              self.extractor = lambda do |object, type, context = nil, *|
75
                unless object.is_a?(::Set)
76
                  message = "Expected Set, got #{object.class}"
77
                  mapping_error(message, context: context)
78
                end
79
                ::Enumerator.new do |yielder|
80
                  object.each_with_index do |value, index|
81
                    attribute = type.attributes[:_value]
82
                    yielder << [attribute, value, Path::Segment.index(index)]
83
                  end
84
                end
85
              end
86
            end
87
88
            INSTANCE = new
89
          end
90
        end
91
      end
92
    end
93
  end
94
end
95