serega 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +319 -141
- data/VERSION +1 -1
- data/lib/serega/attribute.rb +37 -105
- data/lib/serega/attribute_normalizer.rb +176 -0
- data/lib/serega/config.rb +26 -9
- data/lib/serega/object_serializer.rb +11 -10
- data/lib/serega/plan.rb +128 -0
- data/lib/serega/plan_point.rb +94 -0
- data/lib/serega/plugins/batch/batch.rb +187 -41
- data/lib/serega/plugins/batch/lib/loader.rb +4 -4
- data/lib/serega/plugins/batch/lib/loaders.rb +3 -3
- data/lib/serega/plugins/batch/lib/plugins_extensions/activerecord_preloads.rb +2 -2
- data/lib/serega/plugins/batch/lib/plugins_extensions/formatters.rb +19 -1
- data/lib/serega/plugins/batch/lib/plugins_extensions/preloads.rb +6 -4
- data/lib/serega/plugins/batch/lib/validations/check_opt_batch.rb +9 -5
- data/lib/serega/plugins/formatters/formatters.rb +28 -31
- data/lib/serega/plugins/if/if.rb +24 -6
- data/lib/serega/plugins/preloads/lib/format_user_preloads.rb +11 -13
- data/lib/serega/plugins/preloads/lib/main_preload_path.rb +2 -2
- data/lib/serega/plugins/preloads/lib/preloads_constructor.rb +21 -15
- data/lib/serega/plugins/preloads/preloads.rb +72 -40
- data/lib/serega/plugins/presenter/presenter.rb +0 -9
- data/lib/serega/plugins/string_modifiers/parse_string_modifiers.rb +11 -1
- data/lib/serega/plugins.rb +3 -3
- data/lib/serega/utils/enum_deep_dup.rb +18 -18
- data/lib/serega/utils/enum_deep_freeze.rb +35 -0
- data/lib/serega/utils/to_hash.rb +17 -9
- data/lib/serega.rb +22 -15
- metadata +6 -6
- data/lib/serega/map.rb +0 -91
- data/lib/serega/map_point.rb +0 -66
- data/lib/serega/plugins/batch/lib/batch_option_model.rb +0 -73
- data/lib/serega/plugins/preloads/lib/enum_deep_freeze.rb +0 -26
@@ -7,17 +7,6 @@ class Serega
|
|
7
7
|
# Utility that helps to transform user provided preloads to hash
|
8
8
|
#
|
9
9
|
class FormatUserPreloads
|
10
|
-
METHODS = {
|
11
|
-
Array => :array_to_hash,
|
12
|
-
FalseClass => :nil_to_hash,
|
13
|
-
Hash => :hash_to_hash,
|
14
|
-
NilClass => :nil_to_hash,
|
15
|
-
String => :string_to_hash,
|
16
|
-
Symbol => :symbol_to_hash
|
17
|
-
}.freeze
|
18
|
-
|
19
|
-
private_constant :METHODS
|
20
|
-
|
21
10
|
class << self
|
22
11
|
#
|
23
12
|
# Transforms user provided preloads to hash
|
@@ -27,7 +16,16 @@ class Serega
|
|
27
16
|
# @return [Hash] preloads transformed to hash
|
28
17
|
#
|
29
18
|
def call(value)
|
30
|
-
|
19
|
+
case value
|
20
|
+
when Array then array_to_hash(value)
|
21
|
+
when FalseClass then nil_to_hash(value)
|
22
|
+
when Hash then hash_to_hash(value)
|
23
|
+
when NilClass then nil_to_hash(value)
|
24
|
+
when String then string_to_hash(value)
|
25
|
+
when Symbol then symbol_to_hash(value)
|
26
|
+
else raise Serega::SeregaError,
|
27
|
+
"Preload option value can consist from Symbols, Arrays, Hashes (#{value.class} #{value.inspect} was provided)"
|
28
|
+
end
|
31
29
|
end
|
32
30
|
|
33
31
|
private
|
@@ -49,7 +47,7 @@ class Serega
|
|
49
47
|
end
|
50
48
|
|
51
49
|
def string_to_hash(value)
|
52
|
-
|
50
|
+
{value.to_sym => {}}
|
53
51
|
end
|
54
52
|
|
55
53
|
def symbol_to_hash(value)
|
@@ -22,9 +22,9 @@ class Serega
|
|
22
22
|
#
|
23
23
|
# @return [Array<Symbol>] Preloads path to `main` element
|
24
24
|
def call(preloads)
|
25
|
-
return FROZEN_EMPTY_ARRAY if preloads.empty?
|
25
|
+
return FROZEN_EMPTY_ARRAY if !preloads || preloads.empty?
|
26
26
|
|
27
|
-
main_path(preloads)
|
27
|
+
main_path(preloads).freeze
|
28
28
|
end
|
29
29
|
|
30
30
|
private
|
@@ -4,39 +4,39 @@ class Serega
|
|
4
4
|
module SeregaPlugins
|
5
5
|
module Preloads
|
6
6
|
#
|
7
|
-
# Finds preloads for provided attributes
|
7
|
+
# Finds preloads for provided attributes plan
|
8
8
|
#
|
9
9
|
class PreloadsConstructor
|
10
10
|
class << self
|
11
11
|
#
|
12
|
-
# Constructs preloads hash for given attributes
|
12
|
+
# Constructs preloads hash for given attributes plan
|
13
13
|
#
|
14
|
-
# @param
|
14
|
+
# @param plan [Array<Serega::PlanPoint>] Serialization plan
|
15
15
|
#
|
16
16
|
# @return [Hash]
|
17
17
|
#
|
18
|
-
def call(
|
19
|
-
return FROZEN_EMPTY_HASH unless
|
18
|
+
def call(plan)
|
19
|
+
return FROZEN_EMPTY_HASH unless plan
|
20
20
|
|
21
21
|
preloads = {}
|
22
|
-
append_many(preloads,
|
22
|
+
append_many(preloads, plan)
|
23
23
|
preloads
|
24
24
|
end
|
25
25
|
|
26
26
|
private
|
27
27
|
|
28
|
-
def append_many(preloads,
|
29
|
-
|
28
|
+
def append_many(preloads, plan)
|
29
|
+
plan.points.each do |point|
|
30
30
|
current_preloads = point.attribute.preloads
|
31
31
|
next unless current_preloads
|
32
32
|
|
33
|
-
|
34
|
-
current_preloads = SeregaUtils::EnumDeepDup.call(current_preloads) if
|
33
|
+
child_plan = point.child_plan
|
34
|
+
current_preloads = SeregaUtils::EnumDeepDup.call(current_preloads) if child_plan
|
35
35
|
append_current(preloads, current_preloads)
|
36
|
-
next unless
|
36
|
+
next unless child_plan
|
37
37
|
|
38
|
-
|
39
|
-
append_many(
|
38
|
+
child_preloads = dig?(preloads, point.preloads_path)
|
39
|
+
append_many(child_preloads, child_plan)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -50,8 +50,14 @@ class Serega
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
def
|
54
|
-
|
53
|
+
def dig?(hash, path)
|
54
|
+
return hash if !path || path.empty?
|
55
|
+
|
56
|
+
path.each do |point|
|
57
|
+
hash = hash[point]
|
58
|
+
end
|
59
|
+
|
60
|
+
hash
|
55
61
|
end
|
56
62
|
end
|
57
63
|
end
|
@@ -81,12 +81,12 @@ class Serega
|
|
81
81
|
def self.load_plugin(serializer_class, **_opts)
|
82
82
|
serializer_class.include(InstanceMethods)
|
83
83
|
serializer_class::SeregaAttribute.include(AttributeInstanceMethods)
|
84
|
+
serializer_class::SeregaAttributeNormalizer.include(AttributeNormalizerInstanceMethods)
|
84
85
|
serializer_class::SeregaConfig.include(ConfigInstanceMethods)
|
85
|
-
serializer_class::
|
86
|
+
serializer_class::SeregaPlanPoint.include(PlanPointInstanceMethods)
|
86
87
|
|
87
88
|
serializer_class::CheckAttributeParams.include(CheckAttributeParamsInstanceMethods)
|
88
89
|
|
89
|
-
require_relative "./lib/enum_deep_freeze"
|
90
90
|
require_relative "./lib/format_user_preloads"
|
91
91
|
require_relative "./lib/main_preload_path"
|
92
92
|
require_relative "./lib/preloads_constructor"
|
@@ -122,7 +122,7 @@ class Serega
|
|
122
122
|
module InstanceMethods
|
123
123
|
# @return [Hash] merged preloads of all serialized attributes
|
124
124
|
def preloads
|
125
|
-
@preloads ||= PreloadsConstructor.call(
|
125
|
+
@preloads ||= PreloadsConstructor.call(plan)
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
@@ -199,50 +199,54 @@ class Serega
|
|
199
199
|
# @see Serega::SeregaAttribute::AttributeInstanceMethods
|
200
200
|
#
|
201
201
|
module AttributeInstanceMethods
|
202
|
-
# @return [Hash,nil]
|
203
|
-
|
204
|
-
return @preloads if defined?(@preloads)
|
202
|
+
# @return [Hash, nil] normalized preloads of current attribute
|
203
|
+
attr_reader :preloads
|
205
204
|
|
206
|
-
|
207
|
-
|
205
|
+
# @return [Array] normalized preloads_path of current attribute
|
206
|
+
attr_reader :preloads_path
|
208
207
|
|
209
|
-
|
210
|
-
def preloads_path
|
211
|
-
return @preloads_path if defined?(@preloads_path)
|
208
|
+
private
|
212
209
|
|
213
|
-
|
210
|
+
def set_normalized_vars(normalizer)
|
211
|
+
super
|
212
|
+
@preloads = normalizer.preloads
|
213
|
+
@preloads_path = normalizer.preloads_path
|
214
214
|
end
|
215
|
+
end
|
215
216
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
# @
|
223
|
-
|
224
|
-
|
225
|
-
res = super
|
226
|
-
return res unless res.nil?
|
217
|
+
#
|
218
|
+
# SeregaAttributeNormalizer additional/patched instance methods
|
219
|
+
#
|
220
|
+
# @see SeregaAttributeNormalizer::AttributeInstanceMethods
|
221
|
+
#
|
222
|
+
module AttributeNormalizerInstanceMethods
|
223
|
+
# @return [Hash,nil] normalized attribute preloads
|
224
|
+
def preloads
|
225
|
+
return @preloads if instance_variable_defined?(:@preloads)
|
227
226
|
|
228
|
-
|
227
|
+
@preloads = prepare_preloads
|
229
228
|
end
|
230
229
|
|
231
|
-
|
230
|
+
# @return [Array, nil] normalized attribute preloads path
|
231
|
+
def preloads_path
|
232
|
+
return @preloads_path if instance_variable_defined?(:@preloads_path)
|
232
233
|
|
233
|
-
|
234
|
-
auto = self.class.serializer_class.config.preloads.auto_hide_attributes_with_preload
|
235
|
-
@auto_hide_attribute_with_preloads = auto && !preloads.nil? && (preloads != false) && (preloads != {})
|
234
|
+
@preloads_path = prepare_preloads_path
|
236
235
|
end
|
237
236
|
|
237
|
+
private
|
238
|
+
|
239
|
+
#
|
238
240
|
# Patched in:
|
239
241
|
# - plugin :batch (extension :preloads - skips auto preloads when batch option provided)
|
240
|
-
|
242
|
+
#
|
243
|
+
def prepare_preloads
|
244
|
+
opts = init_opts
|
241
245
|
preloads_provided = opts.key?(:preload)
|
242
246
|
preloads =
|
243
247
|
if preloads_provided
|
244
248
|
opts[:preload]
|
245
|
-
elsif
|
249
|
+
elsif opts.key?(:serializer) && self.class.serializer_class.config.preloads.auto_preload_attributes_with_serializer
|
246
250
|
key
|
247
251
|
elsif opts.key?(:delegate) && self.class.serializer_class.config.preloads.auto_preload_attributes_with_delegate
|
248
252
|
opts[:delegate].fetch(:to)
|
@@ -255,30 +259,58 @@ class Serega
|
|
255
259
|
FormatUserPreloads.call(preloads)
|
256
260
|
end
|
257
261
|
|
258
|
-
def
|
259
|
-
|
262
|
+
def prepare_preloads_path
|
263
|
+
opts = init_opts
|
264
|
+
path = Array(opts[:preload_path]).map!(&:to_sym).freeze
|
260
265
|
path = MainPreloadPath.call(preloads) if path.empty?
|
261
|
-
|
266
|
+
path
|
267
|
+
end
|
268
|
+
|
269
|
+
#
|
270
|
+
# Patch for original `prepare_hide` method
|
271
|
+
#
|
272
|
+
# Marks attribute hidden if auto_hide_attribute_with_preloads option was set and attribute has preloads
|
273
|
+
#
|
274
|
+
def prepare_hide
|
275
|
+
res = super
|
276
|
+
return res unless res.nil?
|
277
|
+
|
278
|
+
if preloads && !preloads.empty?
|
279
|
+
self.class.serializer_class.config.preloads.auto_hide_attributes_with_preload || nil
|
280
|
+
end
|
262
281
|
end
|
263
282
|
end
|
264
283
|
|
265
284
|
#
|
266
|
-
# Serega::
|
285
|
+
# Serega::SeregaPlanPoint additional/patched instance methods
|
267
286
|
#
|
268
|
-
# @see Serega::
|
287
|
+
# @see Serega::SeregaPlanPoint::InstanceMethods
|
269
288
|
#
|
270
|
-
module
|
289
|
+
module PlanPointInstanceMethods
|
271
290
|
#
|
272
291
|
# @return [Hash] preloads for nested attributes
|
273
292
|
#
|
274
|
-
|
275
|
-
@preloads ||= PreloadsConstructor.call(nested_points)
|
276
|
-
end
|
293
|
+
attr_reader :preloads
|
277
294
|
|
278
295
|
#
|
279
296
|
# @return [Array<Symbol>] preloads path for current attribute
|
280
297
|
#
|
281
|
-
|
298
|
+
attr_reader :preloads_path
|
299
|
+
|
300
|
+
private
|
301
|
+
|
302
|
+
def set_normalized_vars
|
303
|
+
super
|
304
|
+
|
305
|
+
@preloads = prepare_preloads
|
306
|
+
@preloads_path = prepare_preloads_path
|
307
|
+
end
|
308
|
+
|
309
|
+
def prepare_preloads
|
310
|
+
PreloadsConstructor.call(child_plan)
|
311
|
+
end
|
312
|
+
|
313
|
+
def prepare_preloads_path
|
282
314
|
attribute.preloads_path
|
283
315
|
end
|
284
316
|
end
|
@@ -80,15 +80,6 @@ class Serega
|
|
80
80
|
# @see Serega
|
81
81
|
#
|
82
82
|
module ClassMethods
|
83
|
-
# Overrides {Serega::ClassMethods#attribute} method, additionally adds method
|
84
|
-
# to Presenter to not hit {Serega::SeregaPlugins::Presenter::Presenter#method_missing}
|
85
|
-
# @see Serega::ClassMethods#attribute
|
86
|
-
def attribute(_name, **_opts, &_block)
|
87
|
-
super.tap do |attribute|
|
88
|
-
self::Presenter.def_delegator(:__getobj__, attribute.key) unless attribute.block
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
83
|
private
|
93
84
|
|
94
85
|
def inherited(subclass)
|
@@ -75,11 +75,21 @@ class Serega
|
|
75
75
|
name = attribute.to_sym
|
76
76
|
attribute.clear
|
77
77
|
|
78
|
-
current_attrs = (
|
78
|
+
current_attrs = dig?(res, path_stack)
|
79
79
|
current_attrs[name] = nested_attributes
|
80
80
|
|
81
81
|
name
|
82
82
|
end
|
83
|
+
|
84
|
+
def dig?(hash, path)
|
85
|
+
return hash if !path || path.empty?
|
86
|
+
|
87
|
+
path.each do |point|
|
88
|
+
hash = hash[point]
|
89
|
+
end
|
90
|
+
|
91
|
+
hash
|
92
|
+
end
|
83
93
|
end
|
84
94
|
end
|
85
95
|
end
|
data/lib/serega/plugins.rb
CHANGED
@@ -13,7 +13,7 @@ class Serega
|
|
13
13
|
# @param mod [Module] Plugin module
|
14
14
|
#
|
15
15
|
# @example Register plugin
|
16
|
-
#
|
16
|
+
# SeregaPlugins.register_plugin(:plugin_name, PluginModule)
|
17
17
|
#
|
18
18
|
# @return [void]
|
19
19
|
#
|
@@ -29,10 +29,10 @@ class Serega
|
|
29
29
|
# @raise [SeregaError] Raises SeregaError when plugin was not found
|
30
30
|
#
|
31
31
|
# @example Find plugin when providing name
|
32
|
-
#
|
32
|
+
# SeregaPlugins.find_plugin(:presenter) # => SeregaPlugins::Presenter
|
33
33
|
#
|
34
34
|
# @example Find plugin when providing plugin itself
|
35
|
-
#
|
35
|
+
# SeregaPlugins.find_plugin(Presenter) # => Presenter
|
36
36
|
#
|
37
37
|
# @return [Class<Module>] Plugin core module
|
38
38
|
#
|
@@ -7,40 +7,40 @@ class Serega
|
|
7
7
|
module SeregaUtils
|
8
8
|
#
|
9
9
|
# Duplicates nested hashes and arrays
|
10
|
+
# It does not duplicate any non-Array and non-Hash values
|
10
11
|
#
|
11
12
|
class EnumDeepDup
|
12
|
-
DUP = {
|
13
|
-
Hash => ->(data) { dup_hash_values(data) },
|
14
|
-
Array => ->(data) { dup_array_values(data) }
|
15
|
-
}.freeze
|
16
|
-
private_constant :DUP
|
17
|
-
|
18
13
|
class << self
|
19
14
|
#
|
20
|
-
# Deeply duplicate provided data
|
15
|
+
# Deeply duplicate provided Array or Hash data
|
16
|
+
# It does not duplicate any non-Array and non-Hash values
|
21
17
|
#
|
22
18
|
# @param data [Hash, Array] Data to duplicate
|
23
19
|
#
|
24
20
|
# @return [Hash, Array] Duplicated data
|
25
21
|
#
|
26
22
|
def call(data)
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
case data
|
24
|
+
when Hash
|
25
|
+
# https://github.com/fastruby/fast-ruby#hash-vs-hashdup-code
|
26
|
+
data = Hash[data] # rubocop:disable Style/HashConversion
|
27
|
+
dup_hash_values(data)
|
28
|
+
when Array
|
29
|
+
data = data.dup
|
30
|
+
dup_array_values(data)
|
31
|
+
end
|
32
|
+
|
33
|
+
data
|
30
34
|
end
|
31
35
|
|
32
36
|
private
|
33
37
|
|
34
|
-
def dup_hash_values(
|
35
|
-
|
36
|
-
duplicate_data[key] = call(value) if value.is_a?(Enumerable)
|
37
|
-
end
|
38
|
+
def dup_hash_values(data)
|
39
|
+
data.transform_values! { |value| call(value) }
|
38
40
|
end
|
39
41
|
|
40
|
-
def dup_array_values(
|
41
|
-
|
42
|
-
value.is_a?(Enumerable) ? call(value) : value
|
43
|
-
end
|
42
|
+
def dup_array_values(data)
|
43
|
+
data.map! { |value| call(value) }
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Serega
|
4
|
+
#
|
5
|
+
# Utilities
|
6
|
+
#
|
7
|
+
module SeregaUtils
|
8
|
+
#
|
9
|
+
# Utility to freeze nested hashes and arrays
|
10
|
+
#
|
11
|
+
class EnumDeepFreeze
|
12
|
+
class << self
|
13
|
+
#
|
14
|
+
# Freezes nested hashes and arrays
|
15
|
+
#
|
16
|
+
# @param data[Hash, Array] data to freeze
|
17
|
+
#
|
18
|
+
# @return [Hash, Array] same deeply frozen data
|
19
|
+
#
|
20
|
+
def call(data)
|
21
|
+
case data
|
22
|
+
when Hash
|
23
|
+
data.transform_values! { |value| call(value) }
|
24
|
+
data.freeze
|
25
|
+
when Array
|
26
|
+
data.map! { |value| call(value) }
|
27
|
+
data.freeze
|
28
|
+
end
|
29
|
+
|
30
|
+
data
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/serega/utils/to_hash.rb
CHANGED
@@ -38,31 +38,39 @@ class Serega
|
|
38
38
|
private
|
39
39
|
|
40
40
|
def array_to_hash(values)
|
41
|
-
return
|
41
|
+
return FROZEN_EMPTY_HASH if values.empty?
|
42
42
|
|
43
|
-
|
44
|
-
|
43
|
+
res = {}
|
44
|
+
values.each do |value|
|
45
|
+
case value
|
46
|
+
when String then res[value.to_sym] = FROZEN_EMPTY_HASH
|
47
|
+
when Symbol then res[value] = FROZEN_EMPTY_HASH
|
48
|
+
else res.merge!(call(value))
|
49
|
+
end
|
45
50
|
end
|
51
|
+
res
|
46
52
|
end
|
47
53
|
|
48
54
|
def hash_to_hash(values)
|
49
|
-
return
|
55
|
+
return FROZEN_EMPTY_HASH if values.empty?
|
50
56
|
|
51
|
-
|
52
|
-
|
57
|
+
res = {}
|
58
|
+
values.each do |key, value|
|
59
|
+
res[key.to_sym] = call(value)
|
53
60
|
end
|
61
|
+
res
|
54
62
|
end
|
55
63
|
|
56
64
|
def nil_to_hash(_value)
|
57
|
-
|
65
|
+
FROZEN_EMPTY_HASH
|
58
66
|
end
|
59
67
|
|
60
68
|
def string_to_hash(value)
|
61
|
-
|
69
|
+
{value.to_sym => FROZEN_EMPTY_HASH}
|
62
70
|
end
|
63
71
|
|
64
72
|
def symbol_to_hash(value)
|
65
|
-
{value =>
|
73
|
+
{value => FROZEN_EMPTY_HASH}
|
66
74
|
end
|
67
75
|
end
|
68
76
|
end
|
data/lib/serega.rb
CHANGED
@@ -16,11 +16,13 @@ end
|
|
16
16
|
require_relative "serega/errors"
|
17
17
|
require_relative "serega/helpers/serializer_class_helper"
|
18
18
|
require_relative "serega/utils/enum_deep_dup"
|
19
|
+
require_relative "serega/utils/enum_deep_freeze"
|
19
20
|
require_relative "serega/utils/symbol_name"
|
20
21
|
require_relative "serega/utils/to_hash"
|
21
22
|
require_relative "serega/json/adapter"
|
22
23
|
|
23
24
|
require_relative "serega/attribute"
|
25
|
+
require_relative "serega/attribute_normalizer"
|
24
26
|
require_relative "serega/validations/utils/check_allowed_keys"
|
25
27
|
require_relative "serega/validations/utils/check_opt_is_bool"
|
26
28
|
require_relative "serega/validations/utils/check_opt_is_hash"
|
@@ -41,8 +43,8 @@ require_relative "serega/validations/check_serialize_params"
|
|
41
43
|
|
42
44
|
require_relative "serega/config"
|
43
45
|
require_relative "serega/object_serializer"
|
44
|
-
require_relative "serega/
|
45
|
-
require_relative "serega/
|
46
|
+
require_relative "serega/plan_point"
|
47
|
+
require_relative "serega/plan"
|
46
48
|
require_relative "serega/plugins"
|
47
49
|
|
48
50
|
class Serega
|
@@ -227,13 +229,17 @@ class Serega
|
|
227
229
|
attribute_class.serializer_class = subclass
|
228
230
|
subclass.const_set(:SeregaAttribute, attribute_class)
|
229
231
|
|
230
|
-
|
231
|
-
|
232
|
-
subclass.const_set(:
|
232
|
+
attribute_normalizer_class = Class.new(self::SeregaAttributeNormalizer)
|
233
|
+
attribute_normalizer_class.serializer_class = subclass
|
234
|
+
subclass.const_set(:SeregaAttributeNormalizer, attribute_normalizer_class)
|
233
235
|
|
234
|
-
|
235
|
-
|
236
|
-
subclass.const_set(:
|
236
|
+
plan_class = Class.new(self::SeregaPlan)
|
237
|
+
plan_class.serializer_class = subclass
|
238
|
+
subclass.const_set(:SeregaPlan, plan_class)
|
239
|
+
|
240
|
+
plan_point_class = Class.new(self::SeregaPlanPoint)
|
241
|
+
plan_point_class.serializer_class = subclass
|
242
|
+
subclass.const_set(:SeregaPlanPoint, plan_point_class)
|
237
243
|
|
238
244
|
object_serializer_class = Class.new(self::SeregaObjectSerializer)
|
239
245
|
object_serializer_class.serializer_class = subclass
|
@@ -253,7 +259,8 @@ class Serega
|
|
253
259
|
|
254
260
|
# Assign same attributes
|
255
261
|
attributes.each_value do |attr|
|
256
|
-
|
262
|
+
params = attr.initials
|
263
|
+
subclass.attribute(params[:name], **params[:opts], ¶ms[:block])
|
257
264
|
end
|
258
265
|
|
259
266
|
super
|
@@ -332,12 +339,12 @@ class Serega
|
|
332
339
|
end
|
333
340
|
|
334
341
|
#
|
335
|
-
#
|
336
|
-
# This
|
342
|
+
# Plan for serialization.
|
343
|
+
# This plan can be traversed to find serialized attributes and nested attributes.
|
337
344
|
#
|
338
|
-
# @return [Array<Serega::
|
339
|
-
def
|
340
|
-
@
|
345
|
+
# @return [Array<Serega::SeregaPlanPoint>] plan
|
346
|
+
def plan
|
347
|
+
@plan ||= self.class::SeregaPlan.call(opts)
|
341
348
|
end
|
342
349
|
|
343
350
|
private
|
@@ -373,7 +380,7 @@ class Serega
|
|
373
380
|
# - plugin :metadata (adds metadata to final result)
|
374
381
|
def serialize(object, opts)
|
375
382
|
self.class::SeregaObjectSerializer
|
376
|
-
.new(**opts,
|
383
|
+
.new(**opts, plan: plan)
|
377
384
|
.serialize(object)
|
378
385
|
end
|
379
386
|
end
|
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.11.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: 2023-
|
11
|
+
date: 2023-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
JSON Serializer
|
@@ -29,20 +29,20 @@ files:
|
|
29
29
|
- VERSION
|
30
30
|
- lib/serega.rb
|
31
31
|
- lib/serega/attribute.rb
|
32
|
+
- lib/serega/attribute_normalizer.rb
|
32
33
|
- lib/serega/config.rb
|
33
34
|
- lib/serega/errors.rb
|
34
35
|
- lib/serega/helpers/serializer_class_helper.rb
|
35
36
|
- lib/serega/json/adapter.rb
|
36
37
|
- lib/serega/json/json.rb
|
37
38
|
- lib/serega/json/oj.rb
|
38
|
-
- lib/serega/map.rb
|
39
|
-
- lib/serega/map_point.rb
|
40
39
|
- lib/serega/object_serializer.rb
|
40
|
+
- lib/serega/plan.rb
|
41
|
+
- lib/serega/plan_point.rb
|
41
42
|
- lib/serega/plugins.rb
|
42
43
|
- lib/serega/plugins/activerecord_preloads/activerecord_preloads.rb
|
43
44
|
- lib/serega/plugins/activerecord_preloads/lib/preloader.rb
|
44
45
|
- lib/serega/plugins/batch/batch.rb
|
45
|
-
- lib/serega/plugins/batch/lib/batch_option_model.rb
|
46
46
|
- lib/serega/plugins/batch/lib/loader.rb
|
47
47
|
- lib/serega/plugins/batch/lib/loaders.rb
|
48
48
|
- lib/serega/plugins/batch/lib/plugins_extensions/activerecord_preloads.rb
|
@@ -65,7 +65,6 @@ files:
|
|
65
65
|
- lib/serega/plugins/metadata/validations/check_opt_hide_nil.rb
|
66
66
|
- lib/serega/plugins/metadata/validations/check_opts.rb
|
67
67
|
- lib/serega/plugins/metadata/validations/check_path.rb
|
68
|
-
- lib/serega/plugins/preloads/lib/enum_deep_freeze.rb
|
69
68
|
- lib/serega/plugins/preloads/lib/format_user_preloads.rb
|
70
69
|
- lib/serega/plugins/preloads/lib/main_preload_path.rb
|
71
70
|
- lib/serega/plugins/preloads/lib/preloads_constructor.rb
|
@@ -77,6 +76,7 @@ files:
|
|
77
76
|
- lib/serega/plugins/string_modifiers/parse_string_modifiers.rb
|
78
77
|
- lib/serega/plugins/string_modifiers/string_modifiers.rb
|
79
78
|
- lib/serega/utils/enum_deep_dup.rb
|
79
|
+
- lib/serega/utils/enum_deep_freeze.rb
|
80
80
|
- lib/serega/utils/symbol_name.rb
|
81
81
|
- lib/serega/utils/to_hash.rb
|
82
82
|
- lib/serega/validations/attribute/check_block.rb
|