serega 0.33.0 → 0.33.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5cd7b294e87a2a489db28dc4b77e46a7a359cf667908350a15e74d919a340305
4
- data.tar.gz: e273e63a8a9248b44da6fbd4d71be4fc5be3a01308e42fa8222cec76a94a23e6
3
+ metadata.gz: 94fe2e370dea04c0bedcb7bed7f7f3b6f9ad9ff49a4c39367429929b5bc68e7e
4
+ data.tar.gz: 65cbab835785d14d8c17aba1ba6eff21b8abb9689eba2e4f15e28d68ee60cea9
5
5
  SHA512:
6
- metadata.gz: 94418c706174af2493fa63da4982a732fdaf5841d1664404f20f142d8e4bf798297375d6dc7d082a470a85eea18defa53975076e7778c468ef5f6faa5c8b8f59
7
- data.tar.gz: 7b896b64920aa07a6ba01e4e03967e75cf67a21590978b226e018344e9f116ce0d579289b45eb7a1670989f5fc51591d33546c0f8c9a2dc28ba1fc4ca6120176
6
+ metadata.gz: 9600ce857e2f2fd0836da34cec422eda2472e945a9c3fd94d4e4c9de7fb95e3ddb147b5ac59dc3c575695787fcb9634b9c1fc7cc512590b2da17e6ec492e9271
7
+ data.tar.gz: 7fa17d2686eb63a64b38cd7fea6a006de17497425a77f17a8619d112de8ca7b361549bcc5c0b03fd06c2bf842aec04f366d3aa5c63ae3b40b5e794b666a3a327
data/README.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/serega.svg)](https://badge.fury.io/rb/serega)
4
4
  [![GitHub Actions](https://github.com/aglushkov/serega/actions/workflows/main.yml/badge.svg?event=push)](https://github.com/aglushkov/serega/actions/workflows/main.yml)
5
- [![Test Coverage](https://api.codeclimate.com/v1/badges/f10c0659e16e25e49faa/test_coverage)](https://codeclimate.com/github/aglushkov/serega/test_coverage)
6
- [![Maintainability](https://api.codeclimate.com/v1/badges/f10c0659e16e25e49faa/maintainability)](https://codeclimate.com/github/aglushkov/serega/maintainability)
7
5
 
8
6
  The Serega Ruby Serializer provides easy and powerful DSL to describe your
9
7
  objects and serialize them to Hash or JSON.
@@ -366,8 +364,8 @@ Custom loaders can be provided directly using the `:use` option with any callabl
366
364
  ```ruby
367
365
  class UserSerializer < Serega
368
366
  # Define named loaders
369
- batch_loader :facebook_likes, FacebookLikesLoader
370
- batch_loader :twitter_likes, TwitterLikesLoader
367
+ batch :facebook_likes, FacebookLikesLoader
368
+ batch :twitter_likes, TwitterLikesLoader
371
369
 
372
370
  # Summarize likes
373
371
  attribute :likes_count,
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.33.0
1
+ 0.33.1
@@ -191,22 +191,18 @@ class Serega
191
191
  def prepare_const_block
192
192
  return unless init_opts.key?(:const)
193
193
 
194
- const = init_opts[:const]
195
- proc { const }
194
+ AttributeValueResolvers::ConstResolver.get(init_opts[:const])
196
195
  end
197
196
 
198
197
  def prepare_keyword_block
199
- key_method_name = method_name
200
- proc do |object|
201
- object.public_send(key_method_name)
202
- end
198
+ AttributeValueResolvers::KeywordResolver.get(method_name)
203
199
  end
204
200
 
205
201
  def prepare_batch_loader_block
206
202
  batch_opt = init_opts[:batch]
207
203
  return unless batch_opt
208
204
 
209
- SeregaBatch::AutoResolverFactory.get(self.class.serializer_class, name, batch_opt)
205
+ AttributeValueResolvers::BatchResolver.get(self.class.serializer_class, name, batch_opt)
210
206
  end
211
207
 
212
208
  def prepare_batch_loaders
@@ -238,16 +234,7 @@ class Serega
238
234
  delegate_to = delegate[:to]
239
235
 
240
236
  allow_nil = delegate.fetch(:allow_nil) { config.delegate_default_allow_nil }
241
-
242
- if allow_nil
243
- proc do |object|
244
- object.public_send(delegate_to)&.public_send(key_method_name)
245
- end
246
- else
247
- proc do |object|
248
- object.public_send(delegate_to).public_send(key_method_name)
249
- end
250
- end
237
+ AttributeValueResolvers::DelegateResolver.get(delegate_to, key_method_name, allow_nil)
251
238
  end
252
239
 
253
240
  # Prepares preloads
@@ -1,17 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Serega
4
- module SeregaBatch
4
+ #
5
+ # Attribute value resolvers
6
+ #
7
+ module AttributeValueResolvers
5
8
  #
6
- # Factory generates callable object that should be able to take
7
- # batch loaded results, current object, and find attribute value for this
8
- # object
9
+ # Builds value resolver class for attributes with :batch option
9
10
  #
10
- class AutoResolverFactory
11
+ class BatchResolver
11
12
  #
12
13
  # Generates callable block to find attribute value when attribute with :batch
13
14
  # option has no block or manual :value option.
14
15
  #
16
+ # In other cases we should never get here as attribute value/block option must be manually defined.
17
+ #
15
18
  # It handles this cases:
16
19
  # - `attribute :foo, batch: true`
17
20
  # - `attribute :foo, batch: FooLoader`
@@ -19,8 +22,6 @@ class Serega
19
22
  # - `attribute :foo, batch: { use: FooLoader, id: foo_id }`
20
23
  # - `attribute :foo, batch: { use: :foo_loader, id: foo_id }`
21
24
  #
22
- # In other cases we should never call tis method here.
23
- #
24
25
  def self.get(serializer_class, attribute_name, batch_opt)
25
26
  default_method = serializer_class.config.batch_id_option
26
27
 
@@ -43,7 +44,22 @@ class Serega
43
44
  end
44
45
  end
45
46
 
46
- AutoResolver.new(batch_name, batch_id_method)
47
+ Batch.new(batch_name, batch_id_method)
48
+ end
49
+ end
50
+
51
+ #
52
+ # Builds value resolver class for attributes with :batch option
53
+ #
54
+ class Batch
55
+ def initialize(loader_name, id_method)
56
+ @loader_name = loader_name
57
+ @id_method = id_method
58
+ end
59
+
60
+ # Finds object attribute value from hash of batch_loaded values
61
+ def call(obj, batches:)
62
+ batches.fetch(@loader_name)[obj.public_send(@id_method)]
47
63
  end
48
64
  end
49
65
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ #
5
+ # Attribute value resolvers
6
+ #
7
+ module AttributeValueResolvers
8
+ #
9
+ # Builds value resolver class for attributes with :const option
10
+ #
11
+ class ConstResolver
12
+ #
13
+ # Creates resolver that returns constant value
14
+ #
15
+ # @param const_value [Object] constant value to return
16
+ # @return [Const] resolver instance
17
+ #
18
+ def self.get(const_value)
19
+ Const.new(const_value)
20
+ end
21
+ end
22
+
23
+ #
24
+ # Value resolver class for attributes with :const option
25
+ #
26
+ class Const
27
+ def initialize(const_value)
28
+ @const_value = const_value
29
+ end
30
+
31
+ #
32
+ # Returns the constant value
33
+ #
34
+ # @return [Object] the constant value
35
+ #
36
+ def call
37
+ @const_value
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ #
5
+ # Attribute value resolvers
6
+ #
7
+ module AttributeValueResolvers
8
+ #
9
+ # Builds value resolver class for attributes with :delegate option
10
+ #
11
+ class DelegateResolver
12
+ #
13
+ # Creates resolver that delegates method call to another object
14
+ #
15
+ # @param delegate_to [Symbol] method to call on object to get delegated object
16
+ # @param method_name [Symbol] method to call on delegated object
17
+ # @param allow_nil [Boolean] whether to use safe navigation when delegated object is nil
18
+ # @return [Delegate, DelegateAllowNil] resolver instance
19
+ #
20
+ def self.get(delegate_to, method_name, allow_nil)
21
+ allow_nil ? DelegateAllowNil.new(delegate_to, method_name) : Delegate.new(delegate_to, method_name)
22
+ end
23
+ end
24
+
25
+ #
26
+ # Value resolver class for attributes with :delegate (with :allow_nil) option
27
+ #
28
+ class DelegateAllowNil
29
+ def initialize(delegate_to, method_name)
30
+ @delegate_to = delegate_to
31
+ @method_name = method_name
32
+ end
33
+
34
+ #
35
+ # Delegates method call to another object with safe navigation
36
+ #
37
+ # @param object [Object] the object to delegate from
38
+ # @return [Object, nil] result of delegated method call or nil if delegated object is nil
39
+ #
40
+ def call(object)
41
+ object.public_send(delegate_to)&.public_send(method_name)
42
+ end
43
+
44
+ private
45
+
46
+ attr_reader :delegate_to, :method_name
47
+ end
48
+
49
+ #
50
+ # Value resolver class for attributes with :delegate (without :allow_nil) option
51
+ #
52
+ class Delegate
53
+ def initialize(delegate_to, method_name)
54
+ @delegate_to = delegate_to
55
+ @method_name = method_name
56
+ end
57
+
58
+ #
59
+ # Delegates method call to another object
60
+ #
61
+ # @param object [Object] the object to delegate from
62
+ # @return [Object] result of delegated method call
63
+ #
64
+ def call(object)
65
+ object.public_send(@delegate_to).public_send(@method_name)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ #
5
+ # Attribute value resolvers
6
+ #
7
+ module AttributeValueResolvers
8
+ #
9
+ # Builds value resolver class for attributes with :keyword option
10
+ #
11
+ class KeywordResolver
12
+ #
13
+ # Creates resolver that calls method on object
14
+ #
15
+ # @param keyword [Symbol] method name to call on object
16
+ # @return [Keyword] resolver instance
17
+ #
18
+ def self.get(keyword)
19
+ Keyword.new(keyword)
20
+ end
21
+ end
22
+
23
+ #
24
+ # Value resolver class for attributes with :keyword option
25
+ #
26
+ class Keyword
27
+ def initialize(keyword)
28
+ @keyword = keyword
29
+ end
30
+
31
+ #
32
+ # Calls the keyword method on the object
33
+ #
34
+ # @param object [Object] the object to call method on
35
+ # @return [Object] result of method call
36
+ #
37
+ def call(object)
38
+ object.public_send(@keyword)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -13,7 +13,7 @@ class Serega
13
13
  def initialize(point)
14
14
  @point = point
15
15
  @objects = []
16
- @serialized_object_attachers = {}
16
+ @serialized_object_attachers = []
17
17
  end
18
18
 
19
19
  # Stores object with attacher to find and attach attribute values in batch later.
@@ -22,7 +22,7 @@ class Serega
22
22
  # @return [void]
23
23
  def store(object, attacher)
24
24
  objects << object
25
- serialized_object_attachers[object] = attacher
25
+ serialized_object_attachers << [object, attacher]
26
26
  end
27
27
 
28
28
  # Loads serialized values for all stored objects for current attribute
@@ -128,12 +128,31 @@ class Serega
128
128
 
129
129
  def prepare_if_option(if_option)
130
130
  return unless if_option
131
- return proc { |val| val.public_send(if_option) } if if_option.is_a?(Symbol)
131
+ return KeywordConditionResolver.new(if_option) if if_option.is_a?(Symbol)
132
132
 
133
133
  if_option
134
134
  end
135
135
  end
136
136
 
137
+ #
138
+ # Resolves keyword-based conditions for if/unless options
139
+ #
140
+ class KeywordConditionResolver
141
+ def initialize(keyword)
142
+ @keyword = keyword
143
+ end
144
+
145
+ #
146
+ # Calls the keyword method on the object
147
+ #
148
+ # @param object [Object] the object to call method on
149
+ # @return [Object] result of method call
150
+ #
151
+ def call(object)
152
+ object.public_send(@keyword)
153
+ end
154
+ end
155
+
137
156
  #
138
157
  # SeregaAttribute additional/patched instance methods
139
158
  #
data/lib/serega.rb CHANGED
@@ -23,12 +23,14 @@ require_relative "serega/utils/preload_paths"
23
23
  require_relative "serega/utils/preloads_constructor"
24
24
  require_relative "serega/utils/symbol_name"
25
25
  require_relative "serega/utils/to_hash"
26
+ require_relative "serega/attribute_value_resolvers/batch"
27
+ require_relative "serega/attribute_value_resolvers/const"
28
+ require_relative "serega/attribute_value_resolvers/delegate"
29
+ require_relative "serega/attribute_value_resolvers/keyword"
26
30
  require_relative "serega/attribute"
27
31
  require_relative "serega/attribute_normalizer"
28
32
  require_relative "serega/batch/attribute_loader"
29
33
  require_relative "serega/batch/attribute_loaders"
30
- require_relative "serega/batch/auto_resolver"
31
- require_relative "serega/batch/auto_resolver_factory"
32
34
  require_relative "serega/batch/loader"
33
35
  require_relative "serega/validations/utils/check_allowed_keys"
34
36
  require_relative "serega/validations/utils/check_opt_is_bool"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serega
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.33.0
4
+ version: 0.33.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Glushkov
@@ -29,10 +29,12 @@ files:
29
29
  - lib/serega.rb
30
30
  - lib/serega/attribute.rb
31
31
  - lib/serega/attribute_normalizer.rb
32
+ - lib/serega/attribute_value_resolvers/batch.rb
33
+ - lib/serega/attribute_value_resolvers/const.rb
34
+ - lib/serega/attribute_value_resolvers/delegate.rb
35
+ - lib/serega/attribute_value_resolvers/keyword.rb
32
36
  - lib/serega/batch/attribute_loader.rb
33
37
  - lib/serega/batch/attribute_loaders.rb
34
- - lib/serega/batch/auto_resolver.rb
35
- - lib/serega/batch/auto_resolver_factory.rb
36
38
  - lib/serega/batch/loader.rb
37
39
  - lib/serega/config.rb
38
40
  - lib/serega/errors.rb
@@ -119,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
121
  - !ruby/object:Gem::Version
120
122
  version: '0'
121
123
  requirements: []
122
- rubygems_version: 3.7.1
124
+ rubygems_version: 3.7.2
123
125
  specification_version: 4
124
126
  summary: JSON Serializer
125
127
  test_files: []
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaBatch
5
- #
6
- # Automatically generated resolver for batch_loader
7
- #
8
- class AutoResolver
9
- attr_reader :loader_name
10
- attr_reader :id_method
11
-
12
- def initialize(loader_name, id_method)
13
- @loader_name = loader_name
14
- @id_method = id_method
15
- end
16
-
17
- # Finds object attribute value from hash of batch_loaded values for all
18
- # serialized objects
19
- def call(obj, batches:)
20
- batches.fetch(loader_name)[obj.public_send(id_method)]
21
- end
22
- end
23
- end
24
- end