serega 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/serega/attribute.rb +6 -1
- data/lib/serega/config.rb +2 -2
- data/lib/serega/map.rb +2 -4
- data/lib/serega/map_point.rb +34 -0
- data/lib/serega/object_serializer.rb +67 -0
- data/lib/serega/plugins/activerecord_preloads/activerecord_preloads.rb +4 -0
- data/lib/serega/plugins/activerecord_preloads/lib/preloader.rb +27 -8
- data/lib/serega/plugins/batch/batch.rb +189 -0
- data/lib/serega/plugins/batch/lib/loader.rb +60 -0
- data/lib/serega/plugins/batch/lib/loaders.rb +32 -0
- data/lib/serega/plugins/batch/lib/plugins_extensions.rb +40 -0
- data/lib/serega/plugins/batch/lib/validations/check_batch_opt_key.rb +61 -0
- data/lib/serega/plugins/batch/lib/validations/check_batch_opt_loader.rb +61 -0
- data/lib/serega/plugins/batch/lib/validations/check_opt_batch.rb +47 -0
- data/lib/serega/plugins/context_metadata/context_metadata.rb +4 -4
- data/lib/serega/plugins/formatters/formatters.rb +25 -13
- data/lib/serega/plugins/hide_nil/hide_nil.rb +4 -4
- data/lib/serega/plugins/metadata/metadata.rb +11 -11
- data/lib/serega/plugins/preloads/lib/preloads_constructor.rb +8 -6
- data/lib/serega/plugins/preloads/preloads.rb +12 -1
- data/lib/serega/plugins/presenter/presenter.rb +6 -5
- data/lib/serega/plugins/root/root.rb +12 -12
- data/lib/serega/plugins/string_modifiers/parse_string_modifiers.rb +1 -1
- data/lib/serega/serializer.rb +32 -0
- data/lib/serega.rb +15 -10
- metadata +12 -5
- data/lib/serega/convert.rb +0 -45
- data/lib/serega/convert_item.rb +0 -37
- data/lib/serega/plugins/lazy/lazy.rb +0 -53
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Serega
|
4
|
+
module SeregaPlugins
|
5
|
+
module Batch
|
6
|
+
class CheckOptBatch
|
7
|
+
class << self
|
8
|
+
def call(opts, block)
|
9
|
+
return unless opts.key?(:batch)
|
10
|
+
|
11
|
+
SeregaValidations::Utils::CheckOptIsHash.call(opts, :batch)
|
12
|
+
|
13
|
+
batch = opts[:batch]
|
14
|
+
SeregaValidations::Utils::CheckAllowedKeys.call(batch, %i[key loader default])
|
15
|
+
|
16
|
+
check_batch_opt_key(batch[:key])
|
17
|
+
check_batch_opt_loader(batch[:loader])
|
18
|
+
|
19
|
+
check_usage_with_other_params(opts, block)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def check_batch_opt_key(key)
|
25
|
+
raise SeregaError, "Option :key must present inside :batch option" unless key
|
26
|
+
|
27
|
+
CheckBatchOptKey.call(key)
|
28
|
+
end
|
29
|
+
|
30
|
+
def check_batch_opt_loader(loader)
|
31
|
+
raise SeregaError, "Option :loader must present inside :batch option" unless loader
|
32
|
+
|
33
|
+
CheckBatchOptLoader.call(loader)
|
34
|
+
end
|
35
|
+
|
36
|
+
def check_usage_with_other_params(opts, block)
|
37
|
+
raise SeregaError, "Option :batch can not be used together with option :key" if opts.key?(:key)
|
38
|
+
raise SeregaError, "Option :batch can not be used together with option :value" if opts.key?(:value)
|
39
|
+
raise SeregaError, "Option :batch can not be used together with option :const" if opts.key?(:const)
|
40
|
+
raise SeregaError, "Option :batch can not be used together with option :delegate" if opts.key?(:delegate)
|
41
|
+
raise SeregaError, "Option :batch can not be used together with block" if block
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -15,7 +15,7 @@ class Serega
|
|
15
15
|
|
16
16
|
def self.load_plugin(serializer_class, **_opts)
|
17
17
|
serializer_class::SeregaConfig.include(ConfigInstanceMethods)
|
18
|
-
serializer_class::
|
18
|
+
serializer_class::SeregaSerializer.include(SeregaSerializerInstanceMethods)
|
19
19
|
serializer_class::CheckSerializeParams.include(CheckSerializeParamsInstanceMethods)
|
20
20
|
end
|
21
21
|
|
@@ -44,7 +44,7 @@ class Serega
|
|
44
44
|
|
45
45
|
module ConfigInstanceMethods
|
46
46
|
def context_metadata
|
47
|
-
ContextMetadataConfig.new(opts.fetch(:context_metadata))
|
47
|
+
@context_metadata ||= ContextMetadataConfig.new(opts.fetch(:context_metadata))
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -57,8 +57,8 @@ class Serega
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
module
|
61
|
-
def
|
60
|
+
module SeregaSerializerInstanceMethods
|
61
|
+
def serialize(object)
|
62
62
|
super.tap do |hash|
|
63
63
|
add_context_metadata(hash)
|
64
64
|
end
|
@@ -7,6 +7,12 @@ class Serega
|
|
7
7
|
:formatters
|
8
8
|
end
|
9
9
|
|
10
|
+
def self.before_load_plugin(serializer_class, **opts)
|
11
|
+
if serializer_class.plugin_used?(:batch)
|
12
|
+
raise SeregaError, "Plugin `formatters` must be loaded before `batch`"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
10
16
|
def self.load_plugin(serializer_class, **_opts)
|
11
17
|
serializer_class::SeregaConfig.include(ConfigInstanceMethods)
|
12
18
|
serializer_class::SeregaAttribute.include(AttributeInstanceMethods)
|
@@ -35,21 +41,32 @@ class Serega
|
|
35
41
|
|
36
42
|
module ConfigInstanceMethods
|
37
43
|
def formatters
|
38
|
-
FormattersConfig.new(opts.fetch(:formatters))
|
44
|
+
@formatters ||= FormattersConfig.new(opts.fetch(:formatters))
|
39
45
|
end
|
40
46
|
end
|
41
47
|
|
42
48
|
module AttributeInstanceMethods
|
43
|
-
def
|
44
|
-
return @
|
49
|
+
def formatter
|
50
|
+
return @formatter if instance_variable_defined?(:@formatter)
|
51
|
+
|
52
|
+
@formatter = formatter_resolved
|
53
|
+
end
|
45
54
|
|
46
|
-
|
55
|
+
def formatter_resolved
|
47
56
|
formatter = opts[:format]
|
48
|
-
return
|
57
|
+
return unless formatter
|
49
58
|
|
50
|
-
|
59
|
+
formatter = self.class.serializer_class.config.formatters.opts.fetch(formatter) if formatter.is_a?(Symbol)
|
60
|
+
formatter
|
61
|
+
end
|
62
|
+
|
63
|
+
def value_block
|
64
|
+
return @value_block if instance_variable_defined?(:@value_block)
|
65
|
+
return @value_block = super unless formatter
|
66
|
+
|
67
|
+
new_value_block = formatted_block(formatter, super)
|
51
68
|
|
52
|
-
#
|
69
|
+
# Format :const value in advance
|
53
70
|
if opts.key?(:const)
|
54
71
|
const_value = new_value_block.call
|
55
72
|
new_value_block = proc { const_value }
|
@@ -63,12 +80,7 @@ class Serega
|
|
63
80
|
def formatted_block(formatter, original_block)
|
64
81
|
proc do |object, context|
|
65
82
|
value = original_block.call(object, context)
|
66
|
-
|
67
|
-
if formatter.is_a?(Symbol)
|
68
|
-
self.class.serializer_class.config.formatters.opts.fetch(formatter).call(value)
|
69
|
-
else
|
70
|
-
formatter.call(value)
|
71
|
-
end
|
83
|
+
formatter.call(value)
|
72
84
|
end
|
73
85
|
end
|
74
86
|
end
|
@@ -23,7 +23,7 @@ class Serega
|
|
23
23
|
def self.load_plugin(serializer_class, **_opts)
|
24
24
|
serializer_class::SeregaAttribute.include(AttributeMethods)
|
25
25
|
serializer_class::CheckAttributeParams.include(CheckAttributeParamsInstanceMethods)
|
26
|
-
serializer_class::
|
26
|
+
serializer_class::SeregaObjectSerializer.include(SeregaObjectSerializerInstanceMethods)
|
27
27
|
end
|
28
28
|
|
29
29
|
def self.after_load_plugin(serializer_class, **opts)
|
@@ -66,11 +66,11 @@ class Serega
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
module
|
69
|
+
module SeregaObjectSerializerInstanceMethods
|
70
70
|
private
|
71
71
|
|
72
|
-
def
|
73
|
-
super unless
|
72
|
+
def attach_final_value(final_value, *)
|
73
|
+
super unless final_value.nil?
|
74
74
|
end
|
75
75
|
end
|
76
76
|
end
|
@@ -20,7 +20,7 @@ class Serega
|
|
20
20
|
def self.load_plugin(serializer_class, **_opts)
|
21
21
|
serializer_class.extend(ClassMethods)
|
22
22
|
serializer_class::SeregaConfig.include(ConfigInstanceMethods)
|
23
|
-
serializer_class::
|
23
|
+
serializer_class::SeregaSerializer.include(SeregaSerializerInstanceMethods)
|
24
24
|
|
25
25
|
require_relative "./meta_attribute"
|
26
26
|
require_relative "./validations/check_block"
|
@@ -52,7 +52,7 @@ class Serega
|
|
52
52
|
|
53
53
|
module ConfigInstanceMethods
|
54
54
|
def metadata
|
55
|
-
MetadataConfig.new(opts.fetch(:metadata))
|
55
|
+
@metadata ||= MetadataConfig.new(opts.fetch(:metadata))
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -104,26 +104,26 @@ class Serega
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
-
module
|
108
|
-
def
|
109
|
-
|
110
|
-
|
111
|
-
|
107
|
+
module SeregaSerializerInstanceMethods
|
108
|
+
def serialize(object)
|
109
|
+
super.tap do |hash|
|
110
|
+
add_metadata(object, hash)
|
111
|
+
end
|
112
112
|
end
|
113
113
|
|
114
114
|
private
|
115
115
|
|
116
|
-
def add_metadata(hash)
|
116
|
+
def add_metadata(object, hash)
|
117
117
|
self.class.serializer_class.meta_attributes.each_value do |meta_attribute|
|
118
|
-
metadata = meta_attribute_value(meta_attribute)
|
118
|
+
metadata = meta_attribute_value(object, meta_attribute)
|
119
119
|
next unless metadata
|
120
120
|
|
121
121
|
deep_merge_metadata(hash, metadata)
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
|
-
def meta_attribute_value(meta_attribute)
|
126
|
-
value = meta_attribute.value(object,
|
125
|
+
def meta_attribute_value(object, meta_attribute)
|
126
|
+
value = meta_attribute.value(object, context)
|
127
127
|
return if meta_attribute.hide?(value)
|
128
128
|
|
129
129
|
# Example:
|
@@ -16,6 +16,8 @@ class Serega
|
|
16
16
|
# @return [Hash]
|
17
17
|
#
|
18
18
|
def call(map)
|
19
|
+
return FROZEN_EMPTY_HASH unless map
|
20
|
+
|
19
21
|
preloads = {}
|
20
22
|
append_many(preloads, map)
|
21
23
|
preloads
|
@@ -24,17 +26,17 @@ class Serega
|
|
24
26
|
private
|
25
27
|
|
26
28
|
def append_many(preloads, map)
|
27
|
-
map.each do |
|
28
|
-
current_preloads = attribute.preloads
|
29
|
+
map.each do |point|
|
30
|
+
current_preloads = point.attribute.preloads
|
29
31
|
next unless current_preloads
|
30
32
|
|
31
|
-
has_nested =
|
33
|
+
has_nested = point.has_nested_points?
|
32
34
|
current_preloads = SeregaUtils::EnumDeepDup.call(current_preloads) if has_nested
|
33
35
|
append_current(preloads, current_preloads)
|
34
36
|
next unless has_nested
|
35
37
|
|
36
|
-
nested_preloads = nested(preloads,
|
37
|
-
append_many(nested_preloads,
|
38
|
+
nested_preloads = nested(preloads, point.preloads_path)
|
39
|
+
append_many(nested_preloads, point.nested_points)
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
@@ -49,7 +51,7 @@ class Serega
|
|
49
51
|
end
|
50
52
|
|
51
53
|
def nested(preloads, path)
|
52
|
-
!path || path.empty? ? preloads : preloads.dig(*path)
|
54
|
+
(!path || path.empty?) ? preloads : preloads.dig(*path)
|
53
55
|
end
|
54
56
|
end
|
55
57
|
|
@@ -29,6 +29,7 @@ class Serega
|
|
29
29
|
serializer_class.include(InstanceMethods)
|
30
30
|
serializer_class::SeregaAttribute.include(AttributeMethods)
|
31
31
|
serializer_class::SeregaConfig.include(ConfigInstanceMethods)
|
32
|
+
serializer_class::SeregaMapPoint.include(MapPointMethods)
|
32
33
|
|
33
34
|
serializer_class::CheckAttributeParams.include(CheckAttributeParamsInstanceMethods)
|
34
35
|
|
@@ -85,7 +86,7 @@ class Serega
|
|
85
86
|
|
86
87
|
module ConfigInstanceMethods
|
87
88
|
def preloads
|
88
|
-
PreloadsConfig.new(opts.fetch(:preloads))
|
89
|
+
@preloads ||= PreloadsConfig.new(opts.fetch(:preloads))
|
89
90
|
end
|
90
91
|
end
|
91
92
|
|
@@ -142,6 +143,16 @@ class Serega
|
|
142
143
|
end
|
143
144
|
end
|
144
145
|
|
146
|
+
module MapPointMethods
|
147
|
+
def preloads
|
148
|
+
@preloads ||= PreloadsConstructor.call(nested_points)
|
149
|
+
end
|
150
|
+
|
151
|
+
def preloads_path
|
152
|
+
attribute.preloads_path
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
145
156
|
module CheckAttributeParamsInstanceMethods
|
146
157
|
private
|
147
158
|
|
@@ -35,7 +35,7 @@ class Serega
|
|
35
35
|
#
|
36
36
|
def self.load_plugin(serializer_class, **_opts)
|
37
37
|
serializer_class.extend(ClassMethods)
|
38
|
-
serializer_class::
|
38
|
+
serializer_class::SeregaSerializer.include(SeregaSerializerInstanceMethods)
|
39
39
|
end
|
40
40
|
|
41
41
|
#
|
@@ -94,13 +94,14 @@ class Serega
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
-
# Includes methods to override
|
98
|
-
module
|
97
|
+
# Includes methods to override SeregaSerializer class
|
98
|
+
module SeregaSerializerInstanceMethods
|
99
99
|
#
|
100
100
|
# Replaces serialized object with Presenter.new(object)
|
101
101
|
#
|
102
|
-
def
|
103
|
-
|
102
|
+
def serialize(object)
|
103
|
+
presenter_class = points.first.class.serializer_class::Presenter
|
104
|
+
object = presenter_class.new(object)
|
104
105
|
super
|
105
106
|
end
|
106
107
|
end
|
@@ -12,8 +12,8 @@ class Serega
|
|
12
12
|
|
13
13
|
def self.load_plugin(serializer_class, **_opts)
|
14
14
|
serializer_class.extend(ClassMethods)
|
15
|
-
serializer_class::SeregaConfig.include(
|
16
|
-
serializer_class::
|
15
|
+
serializer_class::SeregaConfig.include(ConfigInstanceMethods)
|
16
|
+
serializer_class::SeregaSerializer.include(SerializerInstanceMethods)
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.after_load_plugin(serializer_class, **opts)
|
@@ -70,9 +70,9 @@ class Serega
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
-
module
|
73
|
+
module ConfigInstanceMethods
|
74
74
|
def root
|
75
|
-
RootConfig.new(opts.fetch(:root))
|
75
|
+
@root ||= RootConfig.new(opts.fetch(:root))
|
76
76
|
end
|
77
77
|
|
78
78
|
def root=(value)
|
@@ -81,21 +81,21 @@ class Serega
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
module
|
85
|
-
def
|
86
|
-
|
87
|
-
root = build_root(opts)
|
88
|
-
|
89
|
-
|
84
|
+
module SerializerInstanceMethods
|
85
|
+
def serialize(_object)
|
86
|
+
result = super
|
87
|
+
root = build_root(result, opts)
|
88
|
+
result = {root => result} if root
|
89
|
+
result
|
90
90
|
end
|
91
91
|
|
92
92
|
private
|
93
93
|
|
94
|
-
def build_root(opts)
|
94
|
+
def build_root(result, opts)
|
95
95
|
return opts[:root] if opts.key?(:root)
|
96
96
|
|
97
97
|
root = self.class.serializer_class.config.root
|
98
|
-
|
98
|
+
result.is_a?(Array) ? root.many : root.one
|
99
99
|
end
|
100
100
|
end
|
101
101
|
end
|
@@ -53,7 +53,7 @@ class Serega
|
|
53
53
|
name = attribute.to_sym
|
54
54
|
attribute.clear
|
55
55
|
|
56
|
-
current_attrs = !path_stack || path_stack.empty? ? res : res.dig(*path_stack)
|
56
|
+
current_attrs = (!path_stack || path_stack.empty?) ? res : res.dig(*path_stack)
|
57
57
|
current_attrs[name] = nested_attributes
|
58
58
|
|
59
59
|
name
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Serega
|
4
|
+
class SeregaSerializer
|
5
|
+
module SeregaSerializerInstanceMethods
|
6
|
+
# @param context [Hash] Serialization context
|
7
|
+
# @param many [TrueClass|FalseClass] is object is enumerable
|
8
|
+
# @param points [Array<MapPoint>] Serialization points (attributes)
|
9
|
+
# @param opts [Hash] Any custom options
|
10
|
+
def initialize(context:, points:, many: nil, **opts)
|
11
|
+
@context = context
|
12
|
+
@points = points
|
13
|
+
@many = many
|
14
|
+
@opts = opts
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param object [Object] Serialized object
|
18
|
+
def serialize(object)
|
19
|
+
self.class.serializer_class::SeregaObjectSerializer
|
20
|
+
.new(context: context, points: points, many: many, **opts)
|
21
|
+
.serialize(object)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :context, :points, :many, :opts
|
27
|
+
end
|
28
|
+
|
29
|
+
extend Serega::SeregaHelpers::SerializerClassHelper
|
30
|
+
include SeregaSerializerInstanceMethods
|
31
|
+
end
|
32
|
+
end
|
data/lib/serega.rb
CHANGED
@@ -37,8 +37,9 @@ require_relative "serega/validations/check_initiate_params"
|
|
37
37
|
require_relative "serega/validations/check_serialize_params"
|
38
38
|
|
39
39
|
require_relative "serega/config"
|
40
|
-
require_relative "serega/
|
41
|
-
require_relative "serega/
|
40
|
+
require_relative "serega/object_serializer"
|
41
|
+
require_relative "serega/serializer"
|
42
|
+
require_relative "serega/map_point"
|
42
43
|
require_relative "serega/map"
|
43
44
|
require_relative "serega/plugins"
|
44
45
|
|
@@ -79,13 +80,17 @@ class Serega
|
|
79
80
|
map_class.serializer_class = subclass
|
80
81
|
subclass.const_set(:SeregaMap, map_class)
|
81
82
|
|
82
|
-
|
83
|
-
|
84
|
-
subclass.const_set(:
|
83
|
+
map_point_class = Class.new(self::SeregaMapPoint)
|
84
|
+
map_point_class.serializer_class = subclass
|
85
|
+
subclass.const_set(:SeregaMapPoint, map_point_class)
|
85
86
|
|
86
|
-
|
87
|
-
|
88
|
-
subclass.const_set(:
|
87
|
+
serega_serializer_class = Class.new(self::SeregaSerializer)
|
88
|
+
serega_serializer_class.serializer_class = subclass
|
89
|
+
subclass.const_set(:SeregaSerializer, serega_serializer_class)
|
90
|
+
|
91
|
+
object_serializer_class = Class.new(self::SeregaObjectSerializer)
|
92
|
+
object_serializer_class.serializer_class = subclass
|
93
|
+
subclass.const_set(:SeregaObjectSerializer, object_serializer_class)
|
89
94
|
|
90
95
|
check_attribute_params_class = Class.new(self::CheckAttributeParams)
|
91
96
|
check_attribute_params_class.serializer_class = subclass
|
@@ -208,7 +213,7 @@ class Serega
|
|
208
213
|
# @param with [Array, Hash, String, Symbol] Attributes (usually hidden) to serialize additionally
|
209
214
|
#
|
210
215
|
def initialize(opts = FROZEN_EMPTY_HASH)
|
211
|
-
@opts = opts == FROZEN_EMPTY_HASH ? opts : prepare_modifiers(opts)
|
216
|
+
@opts = (opts == FROZEN_EMPTY_HASH) ? opts : prepare_modifiers(opts)
|
212
217
|
self.class::CheckInitiateParams.new(@opts).validate if opts.fetch(:check_initiate_params) { config.check_initiate_params }
|
213
218
|
end
|
214
219
|
|
@@ -224,7 +229,7 @@ class Serega
|
|
224
229
|
self.class::CheckSerializeParams.new(opts).validate
|
225
230
|
opts[:context] ||= {}
|
226
231
|
|
227
|
-
self.class::
|
232
|
+
self.class::SeregaSerializer.new(points: map, **opts).serialize(object)
|
228
233
|
end
|
229
234
|
|
230
235
|
# @see #call
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: serega
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrey Glushkov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -21,21 +21,27 @@ files:
|
|
21
21
|
- lib/serega.rb
|
22
22
|
- lib/serega/attribute.rb
|
23
23
|
- lib/serega/config.rb
|
24
|
-
- lib/serega/convert.rb
|
25
|
-
- lib/serega/convert_item.rb
|
26
24
|
- lib/serega/errors.rb
|
27
25
|
- lib/serega/helpers/serializer_class_helper.rb
|
28
26
|
- lib/serega/json/adapter.rb
|
29
27
|
- lib/serega/json/json.rb
|
30
28
|
- lib/serega/json/oj.rb
|
31
29
|
- lib/serega/map.rb
|
30
|
+
- lib/serega/map_point.rb
|
31
|
+
- lib/serega/object_serializer.rb
|
32
32
|
- lib/serega/plugins.rb
|
33
33
|
- lib/serega/plugins/activerecord_preloads/activerecord_preloads.rb
|
34
34
|
- lib/serega/plugins/activerecord_preloads/lib/preloader.rb
|
35
|
+
- lib/serega/plugins/batch/batch.rb
|
36
|
+
- lib/serega/plugins/batch/lib/loader.rb
|
37
|
+
- lib/serega/plugins/batch/lib/loaders.rb
|
38
|
+
- lib/serega/plugins/batch/lib/plugins_extensions.rb
|
39
|
+
- lib/serega/plugins/batch/lib/validations/check_batch_opt_key.rb
|
40
|
+
- lib/serega/plugins/batch/lib/validations/check_batch_opt_loader.rb
|
41
|
+
- lib/serega/plugins/batch/lib/validations/check_opt_batch.rb
|
35
42
|
- lib/serega/plugins/context_metadata/context_metadata.rb
|
36
43
|
- lib/serega/plugins/formatters/formatters.rb
|
37
44
|
- lib/serega/plugins/hide_nil/hide_nil.rb
|
38
|
-
- lib/serega/plugins/lazy/lazy.rb
|
39
45
|
- lib/serega/plugins/metadata/meta_attribute.rb
|
40
46
|
- lib/serega/plugins/metadata/metadata.rb
|
41
47
|
- lib/serega/plugins/metadata/validations/check_block.rb
|
@@ -54,6 +60,7 @@ files:
|
|
54
60
|
- lib/serega/plugins/root/root.rb
|
55
61
|
- lib/serega/plugins/string_modifiers/parse_string_modifiers.rb
|
56
62
|
- lib/serega/plugins/string_modifiers/string_modifiers.rb
|
63
|
+
- lib/serega/serializer.rb
|
57
64
|
- lib/serega/utils/enum_deep_dup.rb
|
58
65
|
- lib/serega/utils/to_hash.rb
|
59
66
|
- lib/serega/validations/attribute/check_block.rb
|
data/lib/serega/convert.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Serega
|
4
|
-
class SeregaConvert
|
5
|
-
module SeregaConvertClassMethods
|
6
|
-
def call(object, **opts)
|
7
|
-
new(object, **opts).to_h
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
module SeregaConvertInstanceMethods
|
12
|
-
attr_reader :object, :opts
|
13
|
-
|
14
|
-
def initialize(object, **opts)
|
15
|
-
@object = object
|
16
|
-
@opts = opts
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_h
|
20
|
-
many? ? many(object) : one(object) || {}
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def many(objects)
|
26
|
-
objects.map { |obj| one(obj) }
|
27
|
-
end
|
28
|
-
|
29
|
-
def one(object)
|
30
|
-
self.class.serializer_class::SeregaConvertItem.call(object, opts[:context], opts[:map])
|
31
|
-
end
|
32
|
-
|
33
|
-
def many?
|
34
|
-
many = opts[:many]
|
35
|
-
return many unless many.nil?
|
36
|
-
|
37
|
-
object.is_a?(Enumerable)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
extend Serega::SeregaHelpers::SerializerClassHelper
|
42
|
-
extend SeregaConvertClassMethods
|
43
|
-
include SeregaConvertInstanceMethods
|
44
|
-
end
|
45
|
-
end
|
data/lib/serega/convert_item.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Serega
|
4
|
-
class SeregaConvertItem
|
5
|
-
module SeregaConvertItemClassMethods
|
6
|
-
def call(object, context, map)
|
7
|
-
return unless object
|
8
|
-
|
9
|
-
map.each_with_object({}) do |(attribute, nested_attributes), hash|
|
10
|
-
value = attribute.value(object, context)
|
11
|
-
attach_value(value, hash, attribute, nested_attributes, context)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
def attach_value(value, hash, attribute, nested_attributes, context)
|
18
|
-
hash[attribute.name] =
|
19
|
-
if nested_attributes.empty?
|
20
|
-
attribute.relation? ? FROZEN_EMPTY_HASH : value
|
21
|
-
elsif many?(attribute, value)
|
22
|
-
value.map { |val| call(val, context, nested_attributes) }
|
23
|
-
else
|
24
|
-
call(value, context, nested_attributes)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def many?(attribute, object)
|
29
|
-
is_many = attribute.many
|
30
|
-
is_many.nil? ? object.is_a?(Enumerable) : is_many
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
extend Serega::SeregaHelpers::SerializerClassHelper
|
35
|
-
extend SeregaConvertItemClassMethods
|
36
|
-
end
|
37
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Serega
|
4
|
-
module SeregaPlugins
|
5
|
-
module Lazy
|
6
|
-
def self.plugin_name
|
7
|
-
:lazy
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.before_load_plugin(serializer_class, **opts)
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.load_plugin(serializer_class, **_opts)
|
14
|
-
serializer_class.extend(ClassMethods)
|
15
|
-
serializer_class.include(InstanceMethods)
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.after_load_plugin(serializer_class, **_opts)
|
19
|
-
serializer_class.config.attribute_keys << :lazy
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
module ClassMethods
|
24
|
-
def lazy(key:, buffer:, resolver:)
|
25
|
-
@lazy[key] = { buffer: buffer, resolver: resolver }
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
module InstanceMethods
|
30
|
-
def initialize(*args, **kwargs)
|
31
|
-
super
|
32
|
-
@lazy = {}
|
33
|
-
end
|
34
|
-
|
35
|
-
def to_h(*args, **kwargs)
|
36
|
-
result = super
|
37
|
-
lazy.each_key do |key, |
|
38
|
-
buffer = lazy.delete(key) # { val => [paths], val2 => [paths2] }
|
39
|
-
buffer_values = self.class.lazy[key][:resolver].(buffer.keys)
|
40
|
-
|
41
|
-
buffer_values.each do |key, resolved_value|
|
42
|
-
paths = buffer[key]
|
43
|
-
paths.each do |path|
|
44
|
-
result.dig(path[0, -2])
|
45
|
-
replace(result, buffer_values)
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
register_plugin(Metadata.plugin_name, Metadata)
|
52
|
-
end
|
53
|
-
end
|