serega 0.6.1 → 0.7.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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/serega/attribute.rb +2 -2
  4. data/lib/serega/config.rb +23 -1
  5. data/lib/serega/errors.rb +8 -5
  6. data/lib/serega/helpers/serializer_class_helper.rb +5 -0
  7. data/lib/serega/json/adapter.rb +6 -0
  8. data/lib/serega/json/json.rb +20 -0
  9. data/lib/serega/json/oj.rb +20 -0
  10. data/lib/serega/map.rb +17 -0
  11. data/lib/serega/map_point.rb +36 -1
  12. data/lib/serega/object_serializer.rb +17 -4
  13. data/lib/serega/plugins/activerecord_preloads/activerecord_preloads.rb +66 -18
  14. data/lib/serega/plugins/activerecord_preloads/lib/preloader.rb +100 -40
  15. data/lib/serega/plugins/batch/batch.rb +136 -10
  16. data/lib/serega/plugins/batch/lib/loader.rb +33 -1
  17. data/lib/serega/plugins/batch/lib/loaders.rb +15 -2
  18. data/lib/serega/plugins/batch/lib/plugins_extensions.rb +23 -1
  19. data/lib/serega/plugins/batch/lib/validations/check_batch_opt_key.rb +12 -0
  20. data/lib/serega/plugins/batch/lib/validations/check_batch_opt_loader.rb +12 -0
  21. data/lib/serega/plugins/batch/lib/validations/check_opt_batch.rb +12 -0
  22. data/lib/serega/plugins/context_metadata/context_metadata.rb +95 -13
  23. data/lib/serega/plugins/formatters/formatters.rb +94 -8
  24. data/lib/serega/plugins/hide_nil/hide_nil.rb +33 -7
  25. data/lib/serega/plugins/metadata/metadata.rb +108 -35
  26. data/lib/serega/plugins/metadata/validations/check_block.rb +3 -0
  27. data/lib/serega/plugins/metadata/validations/check_opt_hide_empty.rb +4 -1
  28. data/lib/serega/plugins/metadata/validations/check_opt_hide_nil.rb +4 -1
  29. data/lib/serega/plugins/metadata/validations/check_opts.rb +3 -0
  30. data/lib/serega/plugins/metadata/validations/check_path.rb +3 -0
  31. data/lib/serega/plugins/preloads/lib/enum_deep_freeze.rb +10 -1
  32. data/lib/serega/plugins/preloads/lib/format_user_preloads.rb +13 -4
  33. data/lib/serega/plugins/preloads/lib/main_preload_path.rb +16 -3
  34. data/lib/serega/plugins/preloads/lib/preloads_constructor.rb +4 -6
  35. data/lib/serega/plugins/preloads/preloads.rb +145 -12
  36. data/lib/serega/plugins/preloads/validations/check_opt_preload.rb +11 -0
  37. data/lib/serega/plugins/preloads/validations/check_opt_preload_path.rb +12 -0
  38. data/lib/serega/plugins/presenter/presenter.rb +20 -11
  39. data/lib/serega/plugins/root/root.rb +131 -19
  40. data/lib/serega/plugins/string_modifiers/parse_string_modifiers.rb +42 -12
  41. data/lib/serega/plugins/string_modifiers/string_modifiers.rb +14 -0
  42. data/lib/serega/plugins.rb +7 -1
  43. data/lib/serega/utils/enum_deep_dup.rb +5 -0
  44. data/lib/serega/utils/to_hash.rb +21 -3
  45. data/lib/serega/validations/attribute/check_block.rb +7 -2
  46. data/lib/serega/validations/attribute/check_name.rb +6 -0
  47. data/lib/serega/validations/attribute/check_opt_const.rb +12 -9
  48. data/lib/serega/validations/attribute/check_opt_delegate.rb +13 -10
  49. data/lib/serega/validations/attribute/check_opt_hide.rb +3 -0
  50. data/lib/serega/validations/attribute/check_opt_key.rb +12 -9
  51. data/lib/serega/validations/attribute/check_opt_many.rb +3 -0
  52. data/lib/serega/validations/attribute/check_opt_serializer.rb +3 -0
  53. data/lib/serega/validations/attribute/check_opt_value.rb +12 -9
  54. data/lib/serega/validations/check_attribute_params.rb +29 -1
  55. data/lib/serega/validations/check_initiate_params.rb +17 -0
  56. data/lib/serega/validations/check_serialize_params.rb +16 -0
  57. data/lib/serega/validations/initiate/check_modifiers.rb +15 -0
  58. data/lib/serega/validations/utils/check_allowed_keys.rb +14 -0
  59. data/lib/serega/validations/utils/check_opt_is_bool.rb +11 -0
  60. data/lib/serega/validations/utils/check_opt_is_hash.rb +11 -0
  61. data/lib/serega/validations/utils/check_opt_is_string_or_symbol.rb +11 -0
  62. data/lib/serega/version.rb +4 -0
  63. data/lib/serega.rb +83 -24
  64. metadata +2 -3
  65. data/lib/serega/serializer.rb +0 -32
@@ -2,14 +2,31 @@
2
2
 
3
3
  class Serega
4
4
  module SeregaValidations
5
+ #
6
+ # Validations of serializer initialization options
7
+ #
5
8
  class CheckInitiateParams
9
+ #
10
+ # Validations of serializer initialization options instance methods
11
+ #
6
12
  module InstanceMethods
13
+ # @return [Hash] validated initialization options
7
14
  attr_reader :opts
8
15
 
16
+ #
17
+ # Initializes validator for initialization options
18
+ #
19
+ # @param opts [Hash] initialization options
20
+ #
21
+ # @return [void]
22
+ #
9
23
  def initialize(opts)
10
24
  @opts = opts
11
25
  end
12
26
 
27
+ #
28
+ # Validates initiating params
29
+ #
13
30
  def validate
14
31
  check_allowed_keys
15
32
  check_modifiers
@@ -2,14 +2,30 @@
2
2
 
3
3
  class Serega
4
4
  module SeregaValidations
5
+ #
6
+ # Validations of serialization options
7
+ #
5
8
  class CheckSerializeParams
9
+ #
10
+ # Validations of serialization options instance methods
11
+ #
6
12
  module InstanceMethods
7
13
  attr_reader :opts
8
14
 
15
+ #
16
+ # Initializes validator for serialization options
17
+ #
18
+ # @param opts [Hash] serialization options
19
+ #
20
+ # @return [void]
21
+ #
9
22
  def initialize(opts)
10
23
  @opts = opts
11
24
  end
12
25
 
26
+ #
27
+ # Validates serialization options
28
+ #
13
29
  def validate
14
30
  check_opts
15
31
  end
@@ -2,9 +2,24 @@
2
2
 
3
3
  class Serega
4
4
  module SeregaValidations
5
+ #
6
+ # Validations that take place when initializing serializer
7
+ #
5
8
  module Initiate
9
+ #
10
+ # Modifiers validation
11
+ #
6
12
  class CheckModifiers
7
13
  class << self
14
+ # Validates provided fields names are existing attributes
15
+ #
16
+ # @param serializer_class [Serega]
17
+ # @param fields [Hash] validated fields
18
+ #
19
+ # @raise [Serega::AttributeNotExist] when modifier not exist as attribute
20
+ #
21
+ # @return [void]
22
+ #
8
23
  def call(serializer_class, fields)
9
24
  return unless fields
10
25
 
@@ -2,8 +2,22 @@
2
2
 
3
3
  class Serega
4
4
  module SeregaValidations
5
+ #
6
+ # Validations Utilities
7
+ #
5
8
  module Utils
9
+ #
10
+ # Utility to check all hash keys are allowed
11
+ #
6
12
  class CheckAllowedKeys
13
+ # Checks hash keys are allowed
14
+ #
15
+ # @param opts [Hash] Some options Hash
16
+ # @param allowed_keys [Array] Allowed hash keys
17
+ #
18
+ # @raise [Serega::SeregaError] error when any hash key is not allowed
19
+ #
20
+ # @return [void]
7
21
  def self.call(opts, allowed_keys)
8
22
  opts.each_key do |key|
9
23
  next if allowed_keys.include?(key)
@@ -3,7 +3,18 @@
3
3
  class Serega
4
4
  module SeregaValidations
5
5
  module Utils
6
+ #
7
+ # Utility to check hash key value is boolean
8
+ #
6
9
  class CheckOptIsBool
10
+ # Checks hash key has boolean value
11
+ #
12
+ # @param opts [Hash] Some options Hash
13
+ # @param key [Object] Hash key
14
+ #
15
+ # @raise [Serega::SeregaError] error when provided key exists and value is not boolean
16
+ #
17
+ # @return [void]
7
18
  def self.call(opts, key)
8
19
  return unless opts.key?(key)
9
20
 
@@ -3,7 +3,18 @@
3
3
  class Serega
4
4
  module SeregaValidations
5
5
  module Utils
6
+ #
7
+ # Utility to check hash key value is Hash
8
+ #
6
9
  class CheckOptIsHash
10
+ # Checks hash key value is Hash
11
+ #
12
+ # @param opts [Hash] Some options Hash
13
+ # @param key [Object] Hash key
14
+ #
15
+ # @raise [Serega::SeregaError] error when provided key exists and value is not a Hash
16
+ #
17
+ # @return [void]
7
18
  def self.call(opts, key)
8
19
  return unless opts.key?(key)
9
20
 
@@ -3,7 +3,18 @@
3
3
  class Serega
4
4
  module SeregaValidations
5
5
  module Utils
6
+ #
7
+ # Utility to check hash key value is String or Symbol
8
+ #
6
9
  class CheckOptIsStringOrSymbol
10
+ # Checks hash key has String or Symbol value
11
+ #
12
+ # @param opts [Hash] Some options Hash
13
+ # @param key [Object] Hash key
14
+ #
15
+ # @raise [Serega::SeregaError] error when provided key exists and value is not String or Symbol
16
+ #
17
+ # @return [void]
7
18
  def self.call(opts, key)
8
19
  return unless opts.key?(key)
9
20
 
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Serega
4
+ # Serega gem version
5
+ #
6
+ # @return [String] SemVer gem version
7
+ #
4
8
  VERSION = File.read(File.join(File.dirname(__FILE__), "../../VERSION")).strip
5
9
  end
data/lib/serega.rb CHANGED
@@ -38,7 +38,6 @@ require_relative "serega/validations/check_serialize_params"
38
38
 
39
39
  require_relative "serega/config"
40
40
  require_relative "serega/object_serializer"
41
- require_relative "serega/serializer"
42
41
  require_relative "serega/map_point"
43
42
  require_relative "serega/map"
44
43
  require_relative "serega/plugins"
@@ -61,7 +60,9 @@ class Serega
61
60
  check_serialize_params_class.serializer_class = self
62
61
  const_set(:CheckSerializeParams, check_serialize_params_class)
63
62
 
64
- # Core serializer class methods
63
+ #
64
+ # Serializers class methods
65
+ #
65
66
  module ClassMethods
66
67
  # @return [SeregaConfig] current serializer config
67
68
  attr_reader :config
@@ -84,10 +85,6 @@ class Serega
84
85
  map_point_class.serializer_class = subclass
85
86
  subclass.const_set(:SeregaMapPoint, map_point_class)
86
87
 
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
88
  object_serializer_class = Class.new(self::SeregaObjectSerializer)
92
89
  object_serializer_class.serializer_class = subclass
93
90
  subclass.const_set(:SeregaObjectSerializer, object_serializer_class)
@@ -145,7 +142,7 @@ class Serega
145
142
  #
146
143
  # @param name [Symbol, Class<Module>] Plugin name or plugin module itself
147
144
  #
148
- # @return [Boolean]
145
+ # @return [Boolean] Is plugin used
149
146
  #
150
147
  def plugin_used?(name)
151
148
  plugin_name =
@@ -180,37 +177,80 @@ class Serega
180
177
  attributes[attribute.name] = attribute
181
178
  end
182
179
 
180
+ #
181
+ # Serializes provided object to Hash
182
+ #
183
+ # @param object [Object] Serialized object
184
+ # @param opts [Hash] Serializer modifiers and other instantiating options
185
+ # @option opts [Array, Hash, String, Symbol] :only The only attributes to serialize
186
+ # @option opts [Array, Hash, String, Symbol] :except Attributes to hide
187
+ # @option opts [Array, Hash, String, Symbol] :with Attributes (usually hidden) to serialize additionally
188
+ # @option opts [Boolean] :validate Validates provided modifiers (Default is true)
189
+ # @option opts [Hash] :context Serialization context
190
+ # @option opts [Boolean] :many Set true if provided multiple objects (Default `object.is_a?(Enumerable)`)
191
+ #
192
+ # @return [Hash] Serialization result
193
+ #
183
194
  def call(object, opts = FROZEN_EMPTY_HASH)
184
195
  initiate_keys = config.initiate_keys
185
196
  new(opts.slice(*initiate_keys)).to_h(object, opts.except(*initiate_keys))
186
197
  end
187
198
 
199
+ # @see #call
188
200
  def to_h(object, opts = FROZEN_EMPTY_HASH)
189
201
  call(object, opts)
190
202
  end
191
203
 
204
+ #
205
+ # Serializes provided object to JSON string
206
+ #
207
+ # @param object [Object] Serialized object
208
+ # @param opts [Hash] Serializer modifiers and other instantiating options
209
+ # @option opts [Array, Hash, String, Symbol] :only The only attributes to serialize
210
+ # @option opts [Array, Hash, String, Symbol] :except Attributes to hide
211
+ # @option opts [Array, Hash, String, Symbol] :with Attributes (usually hidden) to serialize additionally
212
+ # @option opts [Boolean] :validate Validates provided modifiers (Default is true)
213
+ # @option opts [Hash] :context Serialization context
214
+ # @option opts [Boolean] :many Set true if provided multiple objects (Default `object.is_a?(Enumerable)`)
215
+ #
216
+ # @return [String] Serialization result
217
+ #
192
218
  def to_json(object, opts = FROZEN_EMPTY_HASH)
193
219
  initiate_keys = config.initiate_keys
194
220
  new(opts.slice(*initiate_keys)).to_json(object, opts.except(*initiate_keys))
195
221
  end
196
222
 
223
+ #
224
+ # Serializes provided object as JSON
225
+ #
226
+ # @param object [Object] Serialized object
227
+ # @param opts [Hash] Serializer modifiers and other instantiating options
228
+ # @option opts [Array, Hash, String, Symbol] :only The only attributes to serialize
229
+ # @option opts [Array, Hash, String, Symbol] :except Attributes to hide
230
+ # @option opts [Array, Hash, String, Symbol] :with Attributes (usually hidden) to serialize additionally
231
+ # @option opts [Boolean] :validate Validates provided modifiers (Default is true)
232
+ # @option opts [Hash] :context Serialization context
233
+ # @option opts [Boolean] :many Set true if provided multiple objects (Default `object.is_a?(Enumerable)`)
234
+ #
235
+ # @return [Hash] Serialization result
236
+ #
197
237
  def as_json(object, opts = FROZEN_EMPTY_HASH)
198
238
  config.from_json.call(to_json(object, opts))
199
239
  end
200
240
  end
201
241
 
202
242
  #
203
- # Core serializer instance methods
243
+ # Serializers instance methods
204
244
  #
205
245
  module InstanceMethods
206
- attr_reader :opts
207
-
208
246
  #
209
247
  # Instantiates new Serega class
210
248
  #
211
- # @param only [Array, Hash, String, Symbol] The only attributes to serialize
212
- # @param except [Array, Hash, String, Symbol] Attributes to hide
213
- # @param with [Array, Hash, String, Symbol] Attributes (usually hidden) to serialize additionally
249
+ # @param opts [Hash] Serializer modifiers and other instantiating options
250
+ # @option opts [Array, Hash, String, Symbol] :only The only attributes to serialize
251
+ # @option opts [Array, Hash, String, Symbol] :except Attributes to hide
252
+ # @option opts [Array, Hash, String, Symbol] :with Attributes (usually hidden) to serialize additionally
253
+ # @option opts [Boolean] :validate Validates provided modifiers (Default is true)
214
254
  #
215
255
  def initialize(opts = FROZEN_EMPTY_HASH)
216
256
  @opts = (opts == FROZEN_EMPTY_HASH) ? opts : prepare_modifiers(opts)
@@ -218,10 +258,12 @@ class Serega
218
258
  end
219
259
 
220
260
  #
221
- # Serializes provided object to hash
261
+ # Serializes provided object to Hash
222
262
  #
223
263
  # @param object [Object] Serialized object
224
- # @param opts [Hash] Serialization options, like :context and :many
264
+ # @param opts [Hash] Serializer modifiers and other instantiating options
265
+ # @option opts [Hash] :context Serialization context
266
+ # @option opts [Boolean] :many Set true if provided multiple objects (Default `object.is_a?(Enumerable)`)
225
267
  #
226
268
  # @return [Hash] Serialization result
227
269
  #
@@ -229,7 +271,7 @@ class Serega
229
271
  self.class::CheckSerializeParams.new(opts).validate
230
272
  opts[:context] ||= {}
231
273
 
232
- self.class::SeregaSerializer.new(points: map, **opts).serialize(object)
274
+ serialize(object, opts)
233
275
  end
234
276
 
235
277
  # @see #call
@@ -238,9 +280,12 @@ class Serega
238
280
  end
239
281
 
240
282
  #
241
- # Serializes provided object to json
283
+ # Serializes provided object to JSON string
242
284
  #
243
285
  # @param object [Object] Serialized object
286
+ # @param opts [Hash] Serializer modifiers and other instantiating options
287
+ # @option opts [Hash] :context Serialization context
288
+ # @option opts [Boolean] :many Set true if provided multiple objects (Default `object.is_a?(Enumerable)`)
244
289
  #
245
290
  # @return [Hash] Serialization result
246
291
  #
@@ -250,11 +295,12 @@ class Serega
250
295
  end
251
296
 
252
297
  #
253
- # Serializes provided object as json (uses only JSON-compatible types)
254
- # When you later serialize/de-serialize it from JSON you should receive
255
- # equal object
298
+ # Serializes provided object as JSON
256
299
  #
257
300
  # @param object [Object] Serialized object
301
+ # @param opts [Hash] Serializer modifiers and other instantiating options
302
+ # @option opts [Hash] :context Serialization context
303
+ # @option opts [Boolean] :many Set true if provided multiple objects (Default `object.is_a?(Enumerable)`)
258
304
  #
259
305
  # @return [Hash] Serialization result
260
306
  #
@@ -263,22 +309,35 @@ class Serega
263
309
  config.from_json.call(json)
264
310
  end
265
311
 
312
+ #
313
+ # Array of MapPoints, which are attributes combined with nested attributes.
314
+ # This map can be traversed to find currently serializing attributes.
315
+ #
316
+ # @return [Array<Serega::SeregaMapPoint>] map
317
+ def map
318
+ @map ||= self.class::SeregaMap.call(opts)
319
+ end
320
+
266
321
  private
267
322
 
323
+ attr_reader :opts
324
+
268
325
  def config
269
326
  self.class.config
270
327
  end
271
328
 
272
- def map
273
- @map ||= self.class::SeregaMap.call(opts)
274
- end
275
-
276
329
  def prepare_modifiers(opts)
277
330
  opts.each_with_object({}) do |(key, value), obj|
278
331
  value = SeregaUtils::ToHash.call(value) if (key == :only) || (key == :except) || (key == :with)
279
332
  obj[key] = value
280
333
  end
281
334
  end
335
+
336
+ def serialize(object, opts)
337
+ self.class::SeregaObjectSerializer
338
+ .new(**opts, points: map)
339
+ .serialize(object)
340
+ end
282
341
  end
283
342
 
284
343
  extend ClassMethods
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.6.1
4
+ version: 0.7.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-12-03 00:00:00.000000000 Z
11
+ date: 2022-12-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  JSON Serializer
@@ -68,7 +68,6 @@ files:
68
68
  - lib/serega/plugins/root/root.rb
69
69
  - lib/serega/plugins/string_modifiers/parse_string_modifiers.rb
70
70
  - lib/serega/plugins/string_modifiers/string_modifiers.rb
71
- - lib/serega/serializer.rb
72
71
  - lib/serega/utils/enum_deep_dup.rb
73
72
  - lib/serega/utils/to_hash.rb
74
73
  - lib/serega/validations/attribute/check_block.rb
@@ -1,32 +0,0 @@
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