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 |
|
|
|
|
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
|
|
|
|