serega 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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