@@ 13-92 (lines=80) @@ | ||
10 | ||
11 | module AMA |
|
12 | module Entity |
|
13 | 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 |
@@ 8-87 (lines=80) @@ | ||
5 | ||
6 | module AMA |
|
7 | module Entity |
|
8 | class Mapper |
|
9 | class Type |
|
10 | module Hardwired |
|
11 | # Default Enumerable handler |
|
12 | class EnumerableType < Concrete |
|
13 | def initialize |
|
14 | super(::Enumerable) |
|
15 | attribute!(:_value, parameter!(:T), virtual: true) |
|
16 | ||
17 | define_factory |
|
18 | define_normalizer |
|
19 | define_denormalizer |
|
20 | define_enumerator |
|
21 | define_acceptor |
|
22 | define_extractor |
|
23 | end |
|
24 | ||
25 | private |
|
26 | ||
27 | def define_factory |
|
28 | self.factory = Object.new.tap do |factory| |
|
29 | factory.define_singleton_method(:create) do |*| |
|
30 | [] |
|
31 | end |
|
32 | end |
|
33 | end |
|
34 | ||
35 | def define_normalizer |
|
36 | self.normalizer = lambda do |input, *| |
|
37 | input.map(&:itself) |
|
38 | end |
|
39 | end |
|
40 | ||
41 | def define_denormalizer |
|
42 | self.denormalizer = lambda do |entity, *| |
|
43 | entity |
|
44 | end |
|
45 | end |
|
46 | ||
47 | def define_enumerator |
|
48 | self.enumerator = lambda do |entity, type, *| |
|
49 | ::Enumerator.new do |yielder| |
|
50 | attribute = type.attributes[:_value] |
|
51 | entity.each_with_index do |value, index| |
|
52 | yielder << [attribute, value, Path::Segment.index(index)] |
|
53 | end |
|
54 | end |
|
55 | end |
|
56 | end |
|
57 | ||
58 | def define_acceptor |
|
59 | self.acceptor = lambda do |entity, *| |
|
60 | Object.new.tap do |acceptor| |
|
61 | acceptor.define_singleton_method(:accept) do |_, val, segment| |
|
62 | entity[segment.name] = val |
|
63 | end |
|
64 | end |
|
65 | end |
|
66 | end |
|
67 | ||
68 | def define_extractor |
|
69 | self.extractor = lambda do |object, type, context = nil, *| |
|
70 | unless object.is_a?(::Enumerable) |
|
71 | message = "Expected enumerable, got #{object.class}" |
|
72 | mapping_error(message, context: context) |
|
73 | end |
|
74 | ::Enumerator.new do |yielder| |
|
75 | object.each_with_index do |value, index| |
|
76 | attribute = type.attributes[:_value] |
|
77 | yielder << [attribute, value, Path::Segment.index(index)] |
|
78 | end |
|
79 | end |
|
80 | end |
|
81 | end |
|
82 | ||
83 | INSTANCE = new |
|
84 | end |
|
85 | end |
|
86 | end |
|
87 | end |
|
88 | end |
|
89 | end |
|
90 |